summaryrefslogtreecommitdiff
path: root/module
diff options
context:
space:
mode:
Diffstat (limited to 'module')
-rw-r--r--module/NOTICE25
-rw-r--r--module/alphabet.m246
-rw-r--r--module/alphabet/abc.m74
-rw-r--r--module/alphabet/abcstyx.m33
-rw-r--r--module/alphabet/abctypes.m23
-rw-r--r--module/alphabet/endpoints.m14
-rw-r--r--module/alphabet/extvalues.m12
-rw-r--r--module/alphabet/fs.m82
-rw-r--r--module/alphabet/fstypes.m23
-rw-r--r--module/alphabet/grid.m43
-rw-r--r--module/alphabet/gridtypes.m23
-rw-r--r--module/alphabet/reports.m16
-rw-r--r--module/arg.m14
-rw-r--r--module/asn1.m101
-rw-r--r--module/attrdb.m110
-rw-r--r--module/auth9.m103
-rw-r--r--module/bench.m17
-rw-r--r--module/bloomfilter.m7
-rw-r--r--module/brutus.m22
-rw-r--r--module/brutusext.m24
-rw-r--r--module/bufio.m70
-rw-r--r--module/bundle.m9
-rw-r--r--module/cci.m9
-rw-r--r--module/cfg.m25
-rw-r--r--module/cfgfile.m23
-rw-r--r--module/convcs.m29
-rw-r--r--module/crc.m23
-rw-r--r--module/css.m88
-rw-r--r--module/cvsimages.m14
-rw-r--r--module/daytime.m53
-rw-r--r--module/db.m69
-rwxr-xr-xmodule/dbm.m35
-rw-r--r--module/debug.m116
-rw-r--r--module/devpointer.m21
-rw-r--r--module/dhcp.m84
-rw-r--r--module/dialog.m9
-rw-r--r--module/dict.m14
-rw-r--r--module/dis.m323
-rw-r--r--module/diskblocks.m26
-rw-r--r--module/disks.m55
-rw-r--r--module/dividers.m33
-rw-r--r--module/draw.m298
-rw-r--r--module/ecmascript.m334
-rw-r--r--module/emio.m103
-rw-r--r--module/encoding.m11
-rw-r--r--module/env.m10
-rw-r--r--module/ether.m11
-rw-r--r--module/exception.m18
-rw-r--r--module/factotum.m36
-rw-r--r--module/ffts.m32
-rw-r--r--module/filepat.m10
-rw-r--r--module/filter.m25
-rw-r--r--module/format.m30
-rw-r--r--module/freetype.m44
-rw-r--r--module/fslib.m88
-rw-r--r--module/fsproto.m10
-rw-r--r--module/gamer.m16
-rw-r--r--module/gr.m51
-rw-r--r--module/grid/announce.m5
-rw-r--r--module/grid/browse.m43
-rw-r--r--module/grid/browser.m97
-rw-r--r--module/grid/demo/block.m14
-rw-r--r--module/grid/demo/exproc.m7
-rw-r--r--module/grid/fbrowse.m13
-rw-r--r--module/grid/pathreader.m3
-rw-r--r--module/grid/readjpg.m95
-rw-r--r--module/grid/regpoll.m6
-rw-r--r--module/grid/srvbrowse.m16
-rw-r--r--module/hash.m23
-rw-r--r--module/html.m41
-rw-r--r--module/imagefile.m48
-rw-r--r--module/inflate.m25
-rw-r--r--module/ip.m104
-rw-r--r--module/ipattr.m20
-rw-r--r--module/ir.m43
-rw-r--r--module/itslib.m24
-rw-r--r--module/keyboard.m50
-rw-r--r--module/keyring.m238
-rw-r--r--module/keyset.m8
-rw-r--r--module/libc.m30
-rw-r--r--module/libc0.m40
-rw-r--r--module/linalg.m24
-rw-r--r--module/loader.m48
-rw-r--r--module/lock.m13
-rw-r--r--module/man.m41
-rw-r--r--module/math.m91
-rw-r--r--module/math/geodesy.m58
-rw-r--r--module/math/polyfill.m18
-rw-r--r--module/math/polyhedra.m25
-rw-r--r--module/memfs.m5
-rw-r--r--module/mpeg.m13
-rw-r--r--module/multistyx.m8
-rw-r--r--module/muxclient.m23
-rw-r--r--module/names.m13
-rw-r--r--module/newns.m8
-rw-r--r--module/palm.m213
-rw-r--r--module/palmfile.m140
-rw-r--r--module/pkcs.m176
-rw-r--r--module/plumbmsg.m44
-rw-r--r--module/pop3.m40
-rw-r--r--module/popup.m11
-rw-r--r--module/powerman.m8
-rw-r--r--module/prefab.m113
-rw-r--r--module/print.m88
-rw-r--r--module/profile.m78
-rw-r--r--module/pslib.m7
-rw-r--r--module/quicktime.m73
-rw-r--r--module/rand.m7
-rw-r--r--module/readdir.m19
-rw-r--r--module/regex.m38
-rw-r--r--module/regexutils.m17
-rw-r--r--module/registries.m44
-rw-r--r--module/riff.m96
-rw-r--r--module/runt.m11
-rw-r--r--module/scoretable.m12
-rw-r--r--module/scsiio.m27
-rw-r--r--module/secstore.m28
-rw-r--r--module/security.m59
-rw-r--r--module/selectfile.m13
-rw-r--r--module/sets.m34
-rw-r--r--module/sets32.m33
-rw-r--r--module/sexprs.m41
-rw-r--r--module/sh.m106
-rw-r--r--module/smtp.m22
-rw-r--r--module/sort.m8
-rw-r--r--module/spki.m239
-rw-r--r--module/srv.m17
-rw-r--r--module/srvrunt.b3
-rw-r--r--module/ssl3.m204
-rw-r--r--module/sslsession.m27
-rw-r--r--module/string.m39
-rw-r--r--module/strinttab.m17
-rw-r--r--module/strokes.m122
-rw-r--r--module/styx.m182
-rw-r--r--module/styxconv.m9
-rw-r--r--module/styxlib.m87
-rw-r--r--module/styxpersist.m4
-rw-r--r--module/styxservers.m135
-rw-r--r--module/sys.m160
-rw-r--r--module/tables.m24
-rw-r--r--module/tabs.m16
-rw-r--r--module/tcllib.m6
-rw-r--r--module/tftp.m6
-rw-r--r--module/timers.m17
-rw-r--r--module/titlebar.m18
-rw-r--r--module/tk.m25
-rw-r--r--module/tkclient.m26
-rw-r--r--module/translate.m30
-rw-r--r--module/ubfa.m57
-rw-r--r--module/unbundle.m9
-rw-r--r--module/url.m34
-rw-r--r--module/usb.m130
-rw-r--r--module/venti.m159
-rw-r--r--module/volume.m18
-rw-r--r--module/wait.m9
-rw-r--r--module/watchvars.m13
-rw-r--r--module/webget.m7
-rw-r--r--module/winplace.m6
-rw-r--r--module/wmclient.m49
-rw-r--r--module/wmlib.m21
-rw-r--r--module/wmsrv.m46
-rw-r--r--module/workdir.m8
-rw-r--r--module/x509.m370
-rw-r--r--module/xml.m78
-rw-r--r--module/xpointers.m67
165 files changed, 8748 insertions, 0 deletions
diff --git a/module/NOTICE b/module/NOTICE
new file mode 100644
index 00000000..e8c19e7f
--- /dev/null
+++ b/module/NOTICE
@@ -0,0 +1,25 @@
+This copyright NOTICE applies to all files in this directory and
+subdirectories, unless another copyright notice appears in a given
+file or subdirectory. If you take substantial code from this software to use in
+other programs, you must somehow include with it an appropriate
+copyright notice that includes the copyright notice and the other
+notices below. It is fine (and often tidier) to do that in a separate
+file such as NOTICE, LICENCE or COPYING.
+
+Copyright © 1995-1999 Lucent Technologies Inc.
+Portions Copyright © 1997-2000 Vita Nuova Limited
+Portions Copyright © 2000-2006 Vita Nuova Holdings Limited
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License (`LGPL') as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
diff --git a/module/alphabet.m b/module/alphabet.m
new file mode 100644
index 00000000..8158201c
--- /dev/null
+++ b/module/alphabet.m
@@ -0,0 +1,246 @@
+Alphabet: module {
+ PATH: con "/dis/alphabet/alphabet.dis";
+ ONDEMAND, CHECK: con 1<<iota;
+
+ init: fn();
+ copy: fn(): Alphabet;
+ quit: fn();
+ loadtypeset: fn(qname: string, c: chan of ref Proxy->Typescmd[ref Value], errorc: chan of string): string;
+ declare: fn(qname: string, sig: string, flags: int): string;
+ undeclare: fn(name: string): string;
+ importmodule: fn(qname: string): string;
+ importtype: fn(qname: string): string;
+ importvalue: fn(v: ref Value, qname: string): (ref Value, string);
+ autoconvert: fn(src, dst: string, transform: ref Sh->Cmd, errorc: chan of string): string;
+ define: fn(name: string, expr: ref Sh->Cmd, errorc: chan of string): string;
+ setautodeclare: fn(on: int);
+
+ Decltypeset: adt {
+ name: string;
+ alphabet: string;
+ types: array of string;
+ mods: array of (string, string);
+ };
+ Declarations: adt {
+ typesets: array of Decltypeset;
+ defs: array of (string, string);
+ };
+# getdecls: fn(): ref Declarations;
+# getexprdecls: fn(e: ref Sh->Cmd): ref Declarations;
+# declcompat: fn(d0, d1: ref Declarations): int;
+
+ getmodule: fn(name: string): (string, string, ref Sh->Cmd);
+ gettypesets: fn(): list of string;
+ getmodules: fn(): list of string;
+ gettypesetmodules: fn(tsname: string): chan of string;
+ gettypes: fn(typeset: string): list of string;
+ getautoconversions: fn(): list of (string, string, ref Sh->Cmd);
+ typecompat: fn(t0, t1: string): (int, string);
+ show: fn();
+
+ mkqname: fn(typeset, name: string): string;
+ canon: fn(qname: string): string;
+ splitqname: fn(qname: string): (string, string);
+ parse: fn(expr: string): (ref Sh->Cmd, string);
+
+ eval: fn(expr: ref Sh->Cmd,
+ drawctxt: ref Draw->Context,
+ args: list of ref Value): string;
+ eval0: fn(expr: ref Sh->Cmd,
+ dsttype: string,
+ drawctxt: ref Draw->Context,
+ report: ref Reports->Report,
+ errorc: chan of string,
+ args: list of ref Value,
+ vc: chan of ref Value);
+ rewrite: fn(expr: ref Sh->Cmd, dsttype: string,
+ errorc: chan of string): (ref Sh->Cmd, string);
+
+ Value: adt {
+ free: fn(v: self ref Value, used: int);
+ dup: fn(v: self ref Value): ref Value;
+ gets: fn(v: self ref Value): string;
+ isstring: fn(v: self ref Value): int;
+ type2s: fn(tc: int): string;
+ typec: fn(v: self ref Value): int;
+ typename: fn(v: self ref Value): string;
+
+ c: fn(v: self ref Value): ref Value.Vc;
+ s: fn(v: self ref Value): ref Value.Vs;
+ r: fn(v: self ref Value): ref Value.Vr;
+ f: fn(v: self ref Value): ref Value.Vf;
+ w: fn(v: self ref Value): ref Value.Vw;
+ d: fn(v: self ref Value): ref Value.Vd;
+ z: fn(v: self ref Value): ref Value.Vz;
+
+ pick{
+ Vc =>
+ i: ref Sh->Cmd;
+ Vs =>
+ i: string;
+ Vr =>
+ i: chan of string;
+ Vf or
+ Vw =>
+ i: chan of ref Sys->FD;
+ Vd =>
+ i: Datachan;
+ Vz =>
+ i: Proxyval; # a proxy for the actual value, held by another process
+ }
+ };
+
+ Proxyval: adt {
+ typec: int;
+ id: int;
+ };
+
+ Datachan: adt {
+ d: chan of array of byte;
+ stop: chan of int;
+ };
+};
+
+Mainmodule: module {
+ typesig: fn(): string;
+ init: fn();
+ quit: fn();
+ run: fn(ctxt: ref Draw->Context, r: ref Reports->Report, errorc: chan of string,
+ opts: list of (int, list of ref Alphabet->Value), args: list of ref Alphabet->Value): ref Alphabet->Value;
+};
+
+# evaluate an expression
+Eval: module {
+ PATH: con "/dis/alphabet/eval.dis";
+ init: fn();
+
+ Context: adt[V, M, Ectxt]
+ for {
+ V =>
+ dup: fn(t: self V): V;
+ free: fn(v: self V, used: int);
+ isstring: fn(v: self V): int;
+ gets: fn(t: self V): string;
+ type2s: fn(tc: int): string;
+ typec: fn(t: self V): int;
+ M =>
+ find: fn(c: Ectxt, s: string): (M, string);
+ typesig: fn(m: self M): string;
+ run: fn(m: self M, c: Ectxt, errorc: chan of string,
+ opts: list of (int, list of V), args: list of V): V;
+ mks: fn(c: Ectxt, s: string): V;
+ mkc: fn(c: Ectxt, cmd: ref Sh->Cmd): V;
+ typename2c: fn(s: string): int;
+ cvt: fn(c: Ectxt, v: V, tc: int, errorc: chan of string): V;
+ }
+ {
+ eval: fn(
+ expr: ref Sh->Cmd,
+ ctxt: Ectxt,
+ errorc: chan of string,
+ args: list of V
+ ): V;
+ };
+ cmdusage: fn[V](nil: V, sig: string): string
+ for {
+ V =>
+ type2s: fn(tc: int): string;
+ };
+ usage2sig: fn[V](nil: V, u: string): (string, string)
+ for{
+ V =>
+ typename2c: fn(s: string): int;
+ };
+ blocksig: fn[M, Ectxt](nil: M, ctxt: Ectxt, c: ref Sh->Cmd): (string, string)
+ for{
+ M =>
+ typename2c: fn(s: string): int;
+ find: fn(c: Ectxt, s: string): (M, string);
+ typesig: fn(m: self M): string;
+ };
+ typecompat: fn(t0, t1: string): int;
+ splittype: fn(t: string): (int, string, string);
+};
+
+Extvalues: module {
+ PATH: con "/dis/alphabet/extvalues.dis";
+ Values: adt[V] {
+ lock: chan of int;
+ v: array of (int, V);
+ freeids: list of int;
+ new: fn(): ref Values[V];
+ add: fn(vals: self ref Values, v: V): int;
+ inc: fn(vals: self ref Values, id: int);
+ del: fn(vals: self ref Values, id: int);
+ };
+};
+
+# generic proxy implementation:
+Proxy: module {
+ PATH: con "/dis/alphabet/proxy.dis";
+
+ # operators on a type system
+ Typescmd: adt[V] {
+ pick {
+ Load =>
+ cmd: string;
+ reply: chan of (chan of ref Modulecmd[V], string);
+ Dup =>
+ v: V;
+ reply: chan of V;
+ Free =>
+ v: V;
+ used: int;
+ reply: chan of int;
+ Alphabet =>
+ reply: chan of string;
+ Type2s =>
+ tc: int;
+ reply: chan of string;
+ Loadtypes =>
+ name: string;
+ reply: chan of (chan of ref Typescmd[V], string);
+ Modules =>
+ reply: chan of string;
+ }
+ };
+
+ # proxy for a loaded module.
+ Modulecmd: adt[V] {
+ pick {
+ Typesig =>
+ reply: chan of string;
+ Run =>
+ ctxt: ref Draw->Context;
+ report: ref Reports->Report;
+ errorc: chan of string;
+# stopc: chan of int;
+ opts: list of (int, list of V);
+ args: list of V;
+ reply: chan of V;
+ }
+ };
+
+ proxy: fn[Ctxt,Cvt,M,V,EV](ctxt: Ctxt): (
+ chan of ref Proxy->Typescmd[EV],
+ chan of (string, chan of ref Proxy->Typescmd[V])
+ ) for {
+ M =>
+ typesig: fn(m: self M): string;
+ run: fn(m: self M, ctxt: ref Draw->Context, r: ref Reports->Report, errorc: chan of string,
+ opts: list of (int, list of V), args: list of V): V;
+ quit: fn(m: self M);
+ Ctxt =>
+ loadtypes: fn(ctxt: self Ctxt, name: string): (chan of ref Proxy->Typescmd[V], string);
+ type2s: fn(ctxt: self Ctxt, tc: int): string;
+ alphabet: fn(ctxt: self Ctxt): string;
+ modules: fn(ctxt: self Ctxt, r: chan of string);
+ find: fn(ctxt: self Ctxt, s: string): (M, string);
+ getcvt: fn(ctxt: self Ctxt): Cvt;
+ Cvt =>
+ int2ext: fn(cvt: self Cvt, v: V): EV;
+ ext2int: fn(cvt: self Cvt, ev: EV): V;
+ free: fn(cvt: self Cvt, v: EV, used: int);
+ dup: fn(cvt: self Cvt, v: EV): EV;
+ };
+};
diff --git a/module/alphabet/abc.m b/module/alphabet/abc.m
new file mode 100644
index 00000000..384b8d38
--- /dev/null
+++ b/module/alphabet/abc.m
@@ -0,0 +1,74 @@
+# warning: autogenerated code; don't bother to change this, change mktypeset.b or abc.b instead
+Abc: module {
+ PATH: con "/dis/alphabet/abc.dis";
+ Value: adt {
+ m: fn(v: self ref Value): ref Value.Vm; # vmods
+ t: fn(v: self ref Value): ref Value.Vt; # vtypes
+ A: fn(v: self ref Value): ref Value.VA; # abc
+ w: fn(v: self ref Value): ref Value.Vw; # wfd
+ c: fn(v: self ref Value): ref Value.Vc; # cmd
+ r: fn(v: self ref Value): ref Value.Vr; # status
+ f: fn(v: self ref Value): ref Value.Vf; # fd
+ s: fn(v: self ref Value): ref Value.Vs; # string
+ typec: fn(v: self ref Value): int;
+ type2s: fn(t: int): string;
+ free: fn(v: self ref Value, used: int);
+ dup: fn(v: self ref Value): ref Value;
+ pick {
+ Vm =>
+ i: Modulesval;
+ Vt =>
+ i: Typesval;
+ VA =>
+ i: Abcval;
+ Vw =>
+ i: chan of ref Sys->FD;
+ Vc =>
+ i: ref Sh->Cmd;
+ Vr =>
+ i: chan of string;
+ Vf =>
+ i: chan of ref Sys->FD;
+ Vs =>
+ i: string;
+ }
+ };
+ init: fn();
+ Abcval: adt {
+ refcount: chan of int;
+ alphabet: Alphabet;
+ };
+ Typesval: adt {
+ abc: ref Value.VA;
+ types: list of ref Type;
+ };
+ Modulesval: adt {
+ abc: ref Value.VA;
+ types: list of ref Type;
+ mods: list of (string, string, ref Sh->Cmd);
+ query: chan of (string, chan of (string, ref Sh->Cmd));
+ };
+ Type: adt {
+ name: string;
+ actname: string;
+ nodup: int;
+ destructor: ref Sh->Cmd;
+ };
+ mkabc: fn(alphabet: Alphabet): ref Value.VA;
+
+};
+
+Abcmodule: module {
+ types: fn(): string;
+ init: fn();
+ quit: fn();
+ run: fn(errorc: chan of string, r: ref Reports->Report,
+ opts: list of (int, list of ref Abc->Value), args: list of ref Abc->Value): ref Abc->Value;
+};
+
+Declares: module {
+ PATH: con "/dis/alphabet/abc/declares.dis";
+ init: fn();
+ quit: fn();
+ declares: fn(a: Alphabet, decls: ref Sh->Cmd, errorc: chan of string, stopc: chan of int): string;
+};
diff --git a/module/alphabet/abcstyx.m b/module/alphabet/abcstyx.m
new file mode 100644
index 00000000..227550a9
--- /dev/null
+++ b/module/alphabet/abcstyx.m
@@ -0,0 +1,33 @@
+ABCStyx: module {
+ PATH: con "/dis/alphabet/abcstyx.dis";
+ Value: adt {
+ c: fn(v: self ref Value): ref Value.C; # cmd
+ s: fn(v: self ref Value): ref Value.S; # string
+ w: fn(v: self ref Value): ref Value.W; # wfd
+ x: fn(v: self ref Value): ref Value.D; # styx
+
+ typec: fn(v: self ref Value): int;
+ type2s: fn(t: int): string;
+ discard: fn(v: self ref Value);
+ reusable: fn(v: self ref Value): int;
+
+ pick {
+ S =>
+ i: string;
+ C =>
+ i: ref Sh->Cmd;
+ W =>
+ i: chan of ref Sys->FD;
+ X =>
+ i: (chan of ref Styx->Rmsg, chan of ref Styx->Tmsg);
+ }
+ };
+ init: fn();
+};
+
+Styxmodule: module {
+ types: fn(): string;
+ init: fn();
+ run: fn(errorc: chan of string, r: ref Reports->Report,
+ opts: list of (int, list of ref ABCStyx->Value), args: list of ref ABCStyx->Value): ref ABCStyx->Value;
+};
diff --git a/module/alphabet/abctypes.m b/module/alphabet/abctypes.m
new file mode 100644
index 00000000..0acacfdc
--- /dev/null
+++ b/module/alphabet/abctypes.m
@@ -0,0 +1,23 @@
+# warning: autogenerated code; don't bother to change this, change mktypeset.b or abc.b instead
+Abctypes: module {
+ PATH: con "/dis/alphabet/abctypes.dis";
+ Abccvt: adt {
+ values: ref Extvalues->Values[ref Abc->Value];
+
+ int2ext: fn(cvt: self ref Abccvt, v: ref Abc->Value): ref Alphabet->Value;
+ ext2int: fn(cvt: self ref Abccvt, ev: ref Alphabet->Value): ref Abc->Value;
+ dup: fn(cvt: self ref Abccvt, ev: ref Alphabet->Value): ref Alphabet->Value;
+ free: fn(cvt: self ref Abccvt, ev: ref Alphabet->Value, used: int);
+ };
+
+ proxy: fn(): chan of ref Proxy->Typescmd[ref Alphabet->Value];
+ proxy0: fn(): (
+ chan of ref Proxy->Typescmd[ref Alphabet->Value],
+ chan of (string, chan of ref Proxy->Typescmd[ref Abc->Value]),
+ ref Abccvt
+ );
+};
+
+Abcsubtypes: module {
+ proxy: fn(): chan of ref Proxy->Typescmd[ref Abc->Value];
+};
diff --git a/module/alphabet/endpoints.m b/module/alphabet/endpoints.m
new file mode 100644
index 00000000..b01d8c20
--- /dev/null
+++ b/module/alphabet/endpoints.m
@@ -0,0 +1,14 @@
+Endpoints: module {
+ PATH: con "/dis/alphabet/endpoints.dis";
+ Endpoint: adt {
+ addr: string;
+ id: string;
+ about: string;
+ text: fn(e: self Endpoint): string;
+ mk: fn(s: string): Endpoint;
+ };
+ init: fn();
+ new: fn(net, addr: string, force: int): string;
+ create: fn(addr: string): (ref Sys->FD, Endpoint);
+ open: fn(net: string, ep: Endpoint): (ref Sys->FD, string);
+};
diff --git a/module/alphabet/extvalues.m b/module/alphabet/extvalues.m
new file mode 100644
index 00000000..ffc867ce
--- /dev/null
+++ b/module/alphabet/extvalues.m
@@ -0,0 +1,12 @@
+Extvalues: module {
+ PATH: con "/dis/alphabet/extvalues.dis";
+ Values: adt[V] {
+ lock: chan of int;
+ v: array of (int, V);
+ freeids: list of int;
+ new: fn(): ref Values[V];
+ add: fn(vals: self ref Values, v: V): int;
+ inc: fn(vals: self ref Values, id: int);
+ del: fn(vals: self ref Values, id: int);
+ };
+};
diff --git a/module/alphabet/fs.m b/module/alphabet/fs.m
new file mode 100644
index 00000000..baca3e5b
--- /dev/null
+++ b/module/alphabet/fs.m
@@ -0,0 +1,82 @@
+# warning: autogenerated code; don't bother to change this, change mktypeset.b or fs.b instead
+Fs: module {
+ PATH: con "/dis/alphabet/fs.dis";
+ Value: adt {
+ r: fn(v: self ref Value): ref Value.Vr; # status
+ d: fn(v: self ref Value): ref Value.Vd; # data
+ c: fn(v: self ref Value): ref Value.Vc; # command
+ f: fn(v: self ref Value): ref Value.Vf; # fd
+ s: fn(v: self ref Value): ref Value.Vs; # string
+ m: fn(v: self ref Value): ref Value.Vm; # selector
+ p: fn(v: self ref Value): ref Value.Vp; # gate
+ t: fn(v: self ref Value): ref Value.Vt; # entries
+ x: fn(v: self ref Value): ref Value.Vx; # fs
+ typec: fn(v: self ref Value): int;
+ type2s: fn(t: int): string;
+ free: fn(v: self ref Value, used: int);
+ dup: fn(v: self ref Value): ref Value;
+ pick {
+ Vr =>
+ i: chan of string;
+ Vd =>
+ i: Datachan;
+ Vc =>
+ i: ref Sh->Cmd;
+ Vf =>
+ i: chan of ref Sys->FD;
+ Vs =>
+ i: string;
+ Vm =>
+ i: Cmpchan;
+ Vp =>
+ i: Gatechan;
+ Vt =>
+ i: Entrychan;
+ Vx =>
+ i: Fschan;
+ }
+ };
+ init: fn();
+ sendnulldir: fn(c: Fschan): int;
+ copy: fn(src, dst: Fschan): int;
+ Option: adt {
+ opt: int;
+ args: list of ref Value;
+ };
+ Datachan: adt {
+ d: chan of array of byte;
+ stop: chan of int;
+ };
+ Entrychan: adt {
+ sync: chan of int;
+ c: chan of Entry;
+ };
+ Cmpchan: type chan of (ref Sys->Dir, ref Sys->Dir, chan of int);
+ Entry: type (ref Sys->Dir, string, int);
+ Gatequery: type (Entry, chan of int);
+ Gatechan: type chan of Gatequery;
+ Fsdata: adt {
+ dir: ref Sys->Dir;
+ data: array of byte;
+ };
+ Fschan: type chan of (Fsdata, chan of int);
+ Next, Down, Skip, Quit: con iota;
+ Nilentry: con (nil, nil, 0);
+
+};
+
+Fsmodule: module {
+ types: fn(): string;
+ init: fn();
+ run: fn(ctxt: ref Draw->Context, r: ref Reports->Report,
+ opts: list of Fs->Option, args: list of ref Fs->Value): ref Fs->Value;
+};
+Fsfilter: module {
+ PATH: con "/dis/alphabet/fsfilter.dis";
+ filter: fn[T](t: T, src, dst: Fs->Fschan)
+ for{
+ T =>
+ query: fn(t: self T, d: ref Sys->Dir, name: string, depth: int): int;
+ };
+};
+
diff --git a/module/alphabet/fstypes.m b/module/alphabet/fstypes.m
new file mode 100644
index 00000000..8929fba7
--- /dev/null
+++ b/module/alphabet/fstypes.m
@@ -0,0 +1,23 @@
+# warning: autogenerated code; don't bother to change this, change mktypeset.b or fs.b instead
+Fstypes: module {
+ PATH: con "/dis/alphabet/fstypes.dis";
+ Fscvt: adt {
+ values: ref Extvalues->Values[ref Fs->Value];
+
+ int2ext: fn(cvt: self ref Fscvt, v: ref Fs->Value): ref Alphabet->Value;
+ ext2int: fn(cvt: self ref Fscvt, ev: ref Alphabet->Value): ref Fs->Value;
+ dup: fn(cvt: self ref Fscvt, ev: ref Alphabet->Value): ref Alphabet->Value;
+ free: fn(cvt: self ref Fscvt, ev: ref Alphabet->Value, used: int);
+ };
+
+ proxy: fn(): chan of ref Proxy->Typescmd[ref Alphabet->Value];
+ proxy0: fn(): (
+ chan of ref Proxy->Typescmd[ref Alphabet->Value],
+ chan of (string, chan of ref Proxy->Typescmd[ref Fs->Value]),
+ ref Fscvt
+ );
+};
+
+Fssubtypes: module {
+ proxy: fn(): chan of ref Proxy->Typescmd[ref Fs->Value];
+};
diff --git a/module/alphabet/grid.m b/module/alphabet/grid.m
new file mode 100644
index 00000000..b9042ec0
--- /dev/null
+++ b/module/alphabet/grid.m
@@ -0,0 +1,43 @@
+# warning: autogenerated code; don't bother to change this, change mktypeset.b or grid.b instead
+Grid: module {
+ PATH: con "/dis/alphabet/grid.dis";
+ Value: adt {
+ b: fn(v: self ref Value): ref Value.Vb; # records
+ e: fn(v: self ref Value): ref Value.Ve; # endpoint
+ w: fn(v: self ref Value): ref Value.Vw; # wfd
+ c: fn(v: self ref Value): ref Value.Vc; # cmd
+ r: fn(v: self ref Value): ref Value.Vr; # status
+ f: fn(v: self ref Value): ref Value.Vf; # fd
+ s: fn(v: self ref Value): ref Value.Vs; # string
+ typec: fn(v: self ref Value): int;
+ type2s: fn(t: int): string;
+ free: fn(v: self ref Value, used: int);
+ dup: fn(v: self ref Value): ref Value;
+ pick {
+ Vb =>
+ i: chan of ref Sys->FD;
+ Ve =>
+ i: chan of Endpoints->Endpoint;
+ Vw =>
+ i: chan of ref Sys->FD;
+ Vc =>
+ i: ref Sh->Cmd;
+ Vr =>
+ i: chan of string;
+ Vf =>
+ i: chan of ref Sys->FD;
+ Vs =>
+ i: string;
+ }
+ };
+ init: fn();
+
+};
+
+Gridmodule: module {
+ types: fn(): string;
+ init: fn();
+ run: fn(errorc: chan of string, r: ref Reports->Report,
+ opts: list of (int, list of ref Grid->Value), args: list of ref Grid->Value): ref Grid->Value;
+};
+
diff --git a/module/alphabet/gridtypes.m b/module/alphabet/gridtypes.m
new file mode 100644
index 00000000..dd704f3b
--- /dev/null
+++ b/module/alphabet/gridtypes.m
@@ -0,0 +1,23 @@
+# warning: autogenerated code; don't bother to change this, change mktypeset.b or grid.b instead
+Gridtypes: module {
+ PATH: con "/dis/alphabet/gridtypes.dis";
+ Gridcvt: adt {
+ values: ref Extvalues->Values[ref Grid->Value];
+
+ int2ext: fn(cvt: self ref Gridcvt, v: ref Grid->Value): ref Alphabet->Value;
+ ext2int: fn(cvt: self ref Gridcvt, ev: ref Alphabet->Value): ref Grid->Value;
+ dup: fn(cvt: self ref Gridcvt, ev: ref Alphabet->Value): ref Alphabet->Value;
+ free: fn(cvt: self ref Gridcvt, ev: ref Alphabet->Value, used: int);
+ };
+
+ proxy: fn(): chan of ref Proxy->Typescmd[ref Alphabet->Value];
+ proxy0: fn(): (
+ chan of ref Proxy->Typescmd[ref Alphabet->Value],
+ chan of (string, chan of ref Proxy->Typescmd[ref Grid->Value]),
+ ref Gridcvt
+ );
+};
+
+Gridsubtypes: module {
+ proxy: fn(): chan of ref Proxy->Typescmd[ref Grid->Value];
+};
diff --git a/module/alphabet/reports.m b/module/alphabet/reports.m
new file mode 100644
index 00000000..e1cd49d2
--- /dev/null
+++ b/module/alphabet/reports.m
@@ -0,0 +1,16 @@
+Reports: module {
+ PATH: con "/dis/alphabet/reports.dis";
+ Report: adt {
+ startc: chan of (string, chan of string, chan of int);
+ enablec: chan of int;
+
+ enable: fn(r: self ref Report);
+ start: fn(r: self ref Report, name: string): chan of string;
+ add: fn(r: self ref Report, name: string, errorc: chan of string, stopc: chan of int);
+ };
+ KILL, PROPAGATE: con 1<<iota;
+ reportproc: fn(errorc: chan of string, stopc: chan of int, reply: chan of ref Report);
+ quit: fn(errorc: chan of string);
+ report: fn(errorc: chan of string, err: string);
+ newpgrp: fn(stopc: chan of int, flags: int): chan of int;
+};
diff --git a/module/arg.m b/module/arg.m
new file mode 100644
index 00000000..2924e14f
--- /dev/null
+++ b/module/arg.m
@@ -0,0 +1,14 @@
+Arg : module
+{
+ PATH: con "/dis/lib/arg.dis";
+
+ init: fn(argv: list of string);
+ setusage: fn(usage: string);
+ usage: fn();
+ opt: fn(): int;
+ arg: fn(): string;
+ earg: fn(): string;
+
+ progname: fn(): string;
+ argv: fn(): list of string;
+};
diff --git a/module/asn1.m b/module/asn1.m
new file mode 100644
index 00000000..3ceb85de
--- /dev/null
+++ b/module/asn1.m
@@ -0,0 +1,101 @@
+ASN1: module {
+ PATH: con "/dis/lib/asn1.dis";
+
+ # Tag classes
+ Universal : con 0;
+ Application : con 16r40;
+ Context : con 16r80;
+ Private : con 16rC0;
+
+ # Universal tags
+ BOOLEAN : con 1;
+ INTEGER : con 2;
+ BIT_STRING : con 3;
+ OCTET_STRING : con 4;
+ NULL : con 5;
+ OBJECT_ID: con 6;
+ ObjectDescriptor : con 7;
+ EXTERNAL : con 8;
+ REAL : con 9;
+ ENUMERATED : con 10;
+ EMBEDDED_PDV : con 11;
+ SEQUENCE : con 16; # also SEQUENCE OF
+ SET : con 17; # also SET OF
+ NumericString : con 18;
+ PrintableString : con 19;
+ TeletexString : con 20;
+ VideotexString : con 21;
+ IA5String : con 22;
+ UTCTime : con 23;
+ GeneralizedTime : con 24;
+ GraphicString : con 25;
+ VisibleString : con 26;
+ GeneralString : con 27;
+ UniversalString : con 28;
+ BMPString : con 30;
+
+ Elem: adt {
+ tag: Tag;
+ val: ref Value;
+
+ is_seq: fn(e: self ref Elem) : (int, list of ref Elem);
+ is_set: fn(e: self ref Elem) : (int, list of ref Elem);
+ is_int: fn(e: self ref Elem) : (int, int);
+ is_bigint: fn(e: self ref Elem) : (int, array of byte);
+ is_bitstring: fn(e: self ref Elem) : (int, int, array of byte);
+ is_octetstring: fn(e: self ref Elem) : (int, array of byte);
+ is_oid: fn(e: self ref Elem) : (int, ref Oid);
+ is_string: fn(e: self ref Elem) : (int, string);
+ is_time: fn(e: self ref Elem) : (int, string);
+ tostring: fn(e: self ref Elem) : string;
+ };
+
+ Tag: adt {
+ class: int;
+ num: int;
+ constr: int; # ignored by encode()
+
+ tostring: fn(t: self Tag) : string;
+ };
+
+ Value: adt {
+ pick {
+ Bool or Int =>
+ v: int;
+ Octets or BigInt or Real or Other =>
+ # BigInt: integer too big for limbo int
+ # Real: we don't care to decode these
+ # since they are hardly ever used
+ bytes: array of byte;
+ BitString =>
+ # pack into bytes, with perhaps some
+ # unused bits in last byte
+ unusedbits: int;
+ bits: array of byte;
+ Null or EOC =>
+ dummy: int;
+ ObjId =>
+ id: ref Oid;
+ String =>
+ s: string;
+ Seq or Set =>
+ l: list of ref Elem;
+ }
+
+ tostring : fn(v: self ref Value) : string;
+ };
+
+ Oid: adt {
+ nums: array of int;
+
+ tostring: fn(o: self ref Oid) : string;
+ };
+
+ init: fn();
+ decode: fn(a: array of byte) : (string, ref Elem);
+ decode_seq: fn(a: array of byte) : (string, list of ref Elem);
+ decode_value: fn(a: array of byte, kind, constr: int) : (string, ref Value);
+ encode: fn(e: ref Elem) : (string, array of byte);
+ oid_lookup: fn(o: ref Oid, tab: array of Oid) : int;
+ print_elem: fn(e: ref Elem);
+};
diff --git a/module/attrdb.m b/module/attrdb.m
new file mode 100644
index 00000000..bbd2a6ba
--- /dev/null
+++ b/module/attrdb.m
@@ -0,0 +1,110 @@
+Attrdb: module
+{
+ PATH: con "/dis/lib/attrdb.dis";
+
+ Attr: adt {
+ attr: string;
+ val: string;
+ tag: int; # application-defined data, initially 0
+ };
+
+ Tuples: adt {
+ n: int;
+ pairs: list of ref Attr;
+
+ hasattr: fn(t: self ref Tuples, attr: string): int;
+ haspair: fn(t: self ref Tuples, attr: string, value: string): int;
+ find: fn(t: self ref Tuples, attr: string): list of ref Attr;
+ findbyattr: fn(t: self ref Tuples, attr: string, value: string, rattr: string): list of ref Attr;
+ };
+
+ Dbentry: adt {
+ n: int;
+ lines: list of ref Tuples;
+
+ find: fn(e: self ref Dbentry, attr: string): list of (ref Tuples, list of ref Attr);
+ findfirst: fn(e: self ref Dbentry, attr: string): string;
+ findpair: fn(e: self ref Dbentry, attr: string, value: string): list of ref Tuples;
+ findbyattr: fn(e: self ref Dbentry, attr: string, value: string, rattr: string): list of (ref Tuples, list of ref Attr);
+ };
+
+ Dbptr: adt {
+ dbs: list of ref Dbf;
+ index: ref Attrindex->Index;
+ pick{
+ Direct =>
+ offset: int;
+ Hash =>
+ current: int;
+ next: int;
+ }
+ };
+
+ Dbf: adt {
+ fd: ref Bufio->Iobuf;
+ name: string;
+ dir: ref Sys->Dir;
+ indices: list of ref Attrindex->Index;
+ lockc: chan of int;
+
+ open: fn(path: string): ref Dbf;
+ sopen: fn(data: string): ref Dbf;
+ changed: fn(f: self ref Dbf): int;
+ reopen: fn(f: self ref Dbf): int;
+
+ # for supporting commands:
+ readentry: fn(dbf: self ref Dbf, offset: int, attr: string, value: string, useval: int): (ref Dbentry, int, int);
+ };
+
+ Db: adt {
+ dbs: list of ref Dbf;
+
+ open: fn(path: string): ref Db;
+ sopen: fn(data: string): ref Db;
+ append: fn(db1: self ref Db, db2: ref Db): ref Db;
+ changed: fn(db: self ref Db): int;
+ reopen: fn(db: self ref Db): int;
+
+ find: fn(db: self ref Db, start: ref Dbptr, attr: string): (ref Dbentry, ref Dbptr);
+ findpair: fn(db: self ref Db, start: ref Dbptr, attr: string, value: string): (ref Dbentry, ref Dbptr);
+ findbyattr: fn(db: self ref Db, start: ref Dbptr, attr: string, value: string, rattr: string): (ref Dbentry, ref Dbptr);
+ };
+
+ init: fn(): string;
+
+ parseentry: fn(s: string, lno: int): (ref Dbentry, int, string);
+ parseline: fn(s: string, lno: int): (ref Tuples, string);
+};
+
+Attrindex: module
+{
+ PATH: con "/dis/lib/attrhash.dis";
+
+ Index: adt {
+ fd: ref Sys->FD;
+ attr: string;
+ mtime: int;
+ size: int;
+ tab: array of byte;
+
+ open: fn(dbf: Attrdb->Dbf, attr: string, fd: ref Sys->FD): ref Index;
+ };
+
+ init: fn(): string;
+};
+
+Attrhash: module
+{
+ PATH: con "/dis/lib/attrhash.dis";
+
+ NDBPLEN: con 3; # file pointer length in bytes
+ NDBHLEN: con 4+4; # file header length (mtime[4], length[4])
+ NDBSPEC: con 1<<23; # flag bit for something special
+ NDBCHAIN: con NDBSPEC; # pointer to collision chain
+ NDBNAP: con NDBSPEC | 1; # not a pointer
+
+ init: fn(): string;
+ attrindex: fn(): Attrindex;
+ hash: fn(s: string, hlen: int): int;
+ get3, get4: fn(a: array of byte): int;
+};
diff --git a/module/auth9.m b/module/auth9.m
new file mode 100644
index 00000000..c557385f
--- /dev/null
+++ b/module/auth9.m
@@ -0,0 +1,103 @@
+Auth9: module
+{
+ PATH: con "/dis/lib/auth9.dis";
+
+ #
+ # plan 9 authentication
+ #
+
+ ANAMELEN: con 28; # maximum size of name in previous proto
+ AERRLEN: con 64; # maximum size of errstr in previous proto
+ DOMLEN: con 48; # length of an authentication domain name
+ DESKEYLEN: con 7; # length of a des key for encrypt/decrypt
+ CHALLEN: con 8; # length of a plan9 sk1 challenge
+ NETCHLEN: con 16; # max network challenge length (used in AS protocol)
+ SECRETLEN: con 32; # max length of a secret
+
+ # encryption numberings (anti-replay)
+ AuthTreq: con 1; # ticket request
+ AuthChal: con 2; # challenge box request
+ AuthPass: con 3; # change password
+ AuthOK: con 4; # fixed length reply follows
+ AuthErr: con 5; # error follows
+ AuthMod: con 6; # modify user
+ AuthApop: con 7; # apop authentication for pop3
+ AuthOKvar: con 9; # variable length reply follows
+ AuthChap: con 10; # chap authentication for ppp
+ AuthMSchap: con 11; # MS chap authentication for ppp
+ AuthCram: con 12; # CRAM verification for IMAP (RFC2195 & rfc2104)
+ AuthHttp: con 13; # http domain login
+ AuthVNC: con 14; # VNC server login (deprecated)
+
+
+ AuthTs: con 64; # ticket encrypted with server's key
+ AuthTc: con 65; # ticket encrypted with client's key
+ AuthAs: con 66; # server generated authenticator
+ AuthAc: con 67; # client generated authenticator
+ AuthTp: con 68; # ticket encrypted with client's key for password change
+ AuthHr: con 69; # http reply
+
+ Ticketreq: adt {
+ rtype: int;
+ authid: string; # [ANAMELEN] server's encryption id
+ authdom: string; # [DOMLEN] server's authentication domain
+ chal: array of byte; # [CHALLEN] challenge from server
+ hostid: string; # [ANAMELEN] host's encryption id
+ uid: string; # [ANAMELEN] uid of requesting user on host
+
+ pack: fn(t: self ref Ticketreq): array of byte;
+ unpack: fn(a: array of byte): (int, ref Ticketreq);
+ };
+ TICKREQLEN: con 3*ANAMELEN+CHALLEN+DOMLEN+1;
+
+ Ticket: adt {
+ num: int; # replay protection
+ chal: array of byte; # [CHALLEN] server challenge
+ cuid: string; # [ANAMELEN] uid on client
+ suid: string; # [ANAMELEN] uid on server
+ key: array of byte; # [DESKEYLEN] nonce DES key
+
+ pack: fn(t: self ref Ticket, key: array of byte): array of byte;
+ unpack: fn(a: array of byte, key: array of byte): (int, ref Ticket);
+ };
+ TICKETLEN: con CHALLEN+2*ANAMELEN+DESKEYLEN+1;
+
+ Authenticator: adt {
+ num: int; # replay protection
+ chal: array of byte; # [CHALLEN]
+ id: int; # authenticator id, ++'d with each auth
+
+ pack: fn(f: self ref Authenticator, key: array of byte): array of byte;
+ unpack: fn(a: array of byte, key: array of byte): (int, ref Authenticator);
+ };
+ AUTHENTLEN: con CHALLEN+4+1;
+
+ Passwordreq: adt {
+ num: int;
+ old: array of byte; # [ANAMELEN]
+ new: array of byte; # [ANAMELEN]
+ changesecret: int;
+ secret: array of byte; # [SECRETLEN] new secret
+
+ pack: fn(f: self ref Passwordreq, key: array of byte): array of byte;
+ unpack: fn(a: array of byte, key: array of byte): (int, ref Passwordreq);
+ };
+ PASSREQLEN: con 2*ANAMELEN+1+1+SECRETLEN;
+
+ # secure ID and Plan 9 auth key/request/reply encryption
+ netcrypt: fn(key: array of byte, chal: string): string;
+ passtokey: fn(pw: string): array of byte;
+ des56to64: fn(a: array of byte): array of byte;
+ encrypt: fn(key: array of byte, data: array of byte, n: int);
+ decrypt: fn(key: array of byte, data: array of byte, n: int);
+
+ # dial auth server
+# authdial(netroot: string, authdom: string): ref Sys->FD;
+
+ # exchange messages with auth server
+ _asgetticket: fn(fd: ref Sys->FD, tr: ref Ticketreq, key: array of byte): (ref Ticket, array of byte);
+ _asrdresp: fn(fd: ref Sys->FD, n: int): array of byte;
+
+ init: fn();
+};
+
diff --git a/module/bench.m b/module/bench.m
new file mode 100644
index 00000000..bcafdde5
--- /dev/null
+++ b/module/bench.m
@@ -0,0 +1,17 @@
+# Benchmarking
+
+Bench: module
+{
+ PATH: con "$Bench";
+
+ FD: adt
+ {
+ fd: int;
+ };
+
+ microsec: fn(): big;
+ reset: fn();
+ read: fn(fd: ref FD, buf: array of byte, n: int): int;
+ disablegc: fn();
+ enablegc: fn();
+}; \ No newline at end of file
diff --git a/module/bloomfilter.m b/module/bloomfilter.m
new file mode 100644
index 00000000..d33b656a
--- /dev/null
+++ b/module/bloomfilter.m
@@ -0,0 +1,7 @@
+Bloomfilter: module {
+ PATH: con "/dis/lib/bloomfilter.dis";
+ init: fn();
+ # logm is log base 2 of the number of bits in the bloom filter.
+ # k is number of independent hashes of d that are entered into the filter.
+ filter: fn(d: array of byte, logm, k: int): Sets->Set;
+};
diff --git a/module/brutus.m b/module/brutus.m
new file mode 100644
index 00000000..d86f1d17
--- /dev/null
+++ b/module/brutus.m
@@ -0,0 +1,22 @@
+Brutus: module
+{
+ # Font tags are given as (font*NSIZE + size)
+ Size6, Size8, Size10, Size12, Size16, NSIZE: con iota;
+ Roman, Italic, Bold, Type, NFONT: con iota;
+ NFONTTAG: con NFONT*NSIZE;
+ Example, Caption, List, Listelem, Label, Labelref, Exercise, Heading,
+ Nofill, Author, Title, Index, Indextopic, NTAG: con NFONTTAG + iota;
+ DefFont: con Roman;
+ DefSize: con Size10;
+ TitleFont: con Bold;
+ TitleSize: con Size16;
+ HeadingFont: con Bold;
+ HeadingSize: con Size12;
+
+ fontname: array of string;
+ sizename: array of string;
+ tagname: array of string;
+ tagconfig: array of string;
+
+ init: fn(ctxt: ref Draw->Context, args: list of string);
+};
diff --git a/module/brutusext.m b/module/brutusext.m
new file mode 100644
index 00000000..95c2d2ef
--- /dev/null
+++ b/module/brutusext.m
@@ -0,0 +1,24 @@
+Brutusext: module
+{
+ # More tags, needed by Cook
+ SGML, Text, Par, Extension, Float, Special: con Brutus->NTAG + iota;
+
+ # Output formats
+ FLatex, FLatexProc, FLatexBook, FLatexPart, FLatexSlides, FLatexPaper, FHtml: con iota;
+
+ # Cook element
+ Celem: adt
+ {
+ tag: int;
+ s: string;
+ contents: cyclic ref Celem;
+ parent: cyclic ref Celem;
+ next: cyclic ref Celem;
+ prev: cyclic ref Celem;
+ };
+
+
+ init: fn(sys: Sys, draw: Draw, bufio: Bufio, tk: Tk, tkclient: Tkclient);
+ create: fn(parent: string, t: ref Tk->Toplevel, name, args: string): string;
+ cook: fn(parent: string, fmt: int, args: string) : (ref Celem, string);
+};
diff --git a/module/bufio.m b/module/bufio.m
new file mode 100644
index 00000000..1b392fff
--- /dev/null
+++ b/module/bufio.m
@@ -0,0 +1,70 @@
+Bufio: module
+{
+ PATH: con "/dis/lib/bufio.dis";
+
+ SEEKSTART: con Sys->SEEKSTART;
+ SEEKRELA: con Sys->SEEKRELA;
+ SEEKEND: con Sys->SEEKEND;
+
+ OREAD: con Sys->OREAD;
+ OWRITE: con Sys->OWRITE;
+ ORDWR: con Sys->ORDWR;
+
+ EOF: con -1;
+ ERROR: con -2;
+
+ Iobuf: adt {
+ seek: fn(b: self ref Iobuf, n: big, where: int): big;
+ offset: fn(b: self ref Iobuf): big;
+
+ read: fn(b: self ref Iobuf, a: array of byte, n: int): int;
+ write: fn(b: self ref Iobuf, a: array of byte, n: int): int;
+
+ getb: fn(b: self ref Iobuf): int;
+ getc: fn(b: self ref Iobuf): int;
+ gets: fn(b: self ref Iobuf, sep: int): string;
+ gett: fn(b: self ref Iobuf, sep: string): string;
+
+ ungetb: fn(b: self ref Iobuf): int;
+ ungetc: fn(b: self ref Iobuf): int;
+
+ putb: fn(b: self ref Iobuf, b: byte): int;
+ putc: fn(b: self ref Iobuf, c: int): int;
+ puts: fn(b: self ref Iobuf, s: string): int;
+
+ flush: fn(b: self ref Iobuf): int;
+ close: fn(b: self ref Iobuf);
+
+ setfill: fn(b: self ref Iobuf, f: BufioFill);
+
+ # Internal variables
+ fd: ref Sys->FD; # the file
+ buffer: array of byte; # the buffer
+ index: int; # read/write pointer in buffer
+ size: int; # characters remaining/written
+ dirty: int; # needs flushing
+ bufpos: big; # position in file of buf[0]
+ filpos: big; # current file pointer
+ lastop: int; # OREAD or OWRITE
+ mode: int; # mode of open
+ };
+
+ open: fn(name: string, mode: int): ref Iobuf;
+ create: fn(name: string, mode, perm: int): ref Iobuf;
+ fopen: fn(fd: ref Sys->FD, mode: int): ref Iobuf;
+ sopen: fn(input: string): ref Iobuf;
+ aopen: fn(input: array of byte): ref Iobuf;
+};
+
+BufioFill: module
+{
+ fill: fn(b: ref Bufio->Iobuf): int;
+};
+
+ChanFill: module
+{
+ PATH: con "/dis/lib/chanfill.dis";
+
+ init: fn(data: array of byte, fid: int, wc: Sys->Rwrite, r: ref Sys->FileIO, b: Bufio): ref Bufio->Iobuf;
+ fill: fn(b: ref Bufio->Iobuf): int;
+};
diff --git a/module/bundle.m b/module/bundle.m
new file mode 100644
index 00000000..447b010c
--- /dev/null
+++ b/module/bundle.m
@@ -0,0 +1,9 @@
+Bundle: module {
+ PATH: con "/dis/fs/bundle.dis";
+
+ types: fn(): string;
+ init: fn();
+ run: fn(nil: ref Draw->Context, report: ref Fslib->Report,
+ nil: list of Fslib->Option, args: list of ref Fslib->Value): ref Fslib->Value;
+ bundle: fn(r: ref Fslib->Report, iob: ref Bufio->Iobuf, c: Fslib->Fschan): chan of int;
+};
diff --git a/module/cci.m b/module/cci.m
new file mode 100644
index 00000000..2ee630b9
--- /dev/null
+++ b/module/cci.m
@@ -0,0 +1,9 @@
+CCI: module
+{
+ PATH: con "/dis/lib/cci.dis";
+
+ # Common Client Interface, for external control of Charon
+
+ init: fn(smod: String, hctl: chan of string);
+ view: fn(url, ctype: string, data: array of byte);
+};
diff --git a/module/cfg.m b/module/cfg.m
new file mode 100644
index 00000000..ddc490b8
--- /dev/null
+++ b/module/cfg.m
@@ -0,0 +1,25 @@
+Cfg : module {
+ PATH : con "/dis/lib/cfg.dis";
+
+ Attr : adt {
+ name : string;
+ value : string;
+ };
+
+ Tuple : adt {
+ lnum : int;
+ attrs : list of Attr;
+ lookup: fn (t : self ref Tuple, name : string) : string;
+ };
+
+ Record : adt {
+ tuples : list of ref Tuple;
+ lookup : fn (r : self ref Record, name : string) : (string, ref Tuple);
+ };
+
+ init : fn (path : string) : string;
+ reset: fn();
+ lookup : fn (name : string) : list of (string, ref Record);
+ getkeys : fn () : list of string;
+ parseline: fn(s: string, lno: int): (ref Tuple, string);
+};
diff --git a/module/cfgfile.m b/module/cfgfile.m
new file mode 100644
index 00000000..4aff004a
--- /dev/null
+++ b/module/cfgfile.m
@@ -0,0 +1,23 @@
+#
+# simple adt that operates on whitespace separated config files
+# such as /services/webget/config
+#
+CfgFile: module
+{
+ PATH: con "/dis/lib/cfgfile.dis";
+ ConfigFile: adt
+ {
+ getcfg: fn(me: self ref ConfigFile,field:string):list of string;
+ setcfg: fn(me: self ref ConfigFile,field:string,val:string);
+ delete: fn(me: self ref ConfigFile,field:string);
+ flush: fn(me: self ref ConfigFile): string;
+
+ # ----- private ------
+ lines: list of string;
+ file: string;
+ readonly: int;
+ };
+
+ init: fn(file:string):ref ConfigFile;
+ verify: fn(defaultpath: string, path: string) :ref Sys->FD;
+};
diff --git a/module/convcs.m b/module/convcs.m
new file mode 100644
index 00000000..b139351e
--- /dev/null
+++ b/module/convcs.m
@@ -0,0 +1,29 @@
+#
+# Copyright © 2001 Vita Nuova Limited
+#
+Btos: module {
+ init: fn(arg: string): string;
+ btos: fn(s: Convcs->State, b: array of byte, nchars: int) : (Convcs->State, string, int);
+};
+
+Stob: module {
+ init: fn(arg: string): string;
+ stob: fn(s: Convcs->State, str: string): (Convcs->State, array of byte);
+};
+
+Convcs: module {
+ PATH: con "/dis/lib/convcs/convcs.dis";
+ CHARSETS: con "/lib/charsets";
+
+ BTOS, STOB: con 1 << iota; # enumcs() mode values
+ BOTH: con BTOS | STOB;
+
+ State: type string;
+ Startstate: con "";
+
+ init: fn(csfile: string): string;
+ getbtos: fn(cs: string): (Btos, string);
+ getstob: fn(cs: string): (Stob, string);
+ enumcs: fn(): list of (string, string, int); # (cs, description, mode)
+ aliases: fn(cs : string): (string, list of string);
+};
diff --git a/module/crc.m b/module/crc.m
new file mode 100644
index 00000000..408af38e
--- /dev/null
+++ b/module/crc.m
@@ -0,0 +1,23 @@
+Crc: module
+{
+ PATH: con "/dis/lib/crc.dis";
+
+ CRCstate: adt {
+ crc: int;
+ crctab: array of int;
+ reg: int;
+ };
+
+ # setup crc table with given polynomial (if 0 default polynomial used)
+ # (the polynomial has an implicit top bit set)
+ # reg is the initial value of the CRC register
+ # (usually 0 but 16rfffffffrf in the CRC32 algorithm for example)
+ init: fn(poly: int, reg: int): ref CRCstate;
+
+ # calculate crc of first nb bytes in given array of bytes and return its value
+ # may be called repeatedly to calculate crc of a series of arrays of bytes
+ crc : fn(state: ref CRCstate, buf: array of byte, nb: int): int;
+
+ # reset crc state to its initial value
+ reset: fn(state: ref CRCstate);
+};
diff --git a/module/css.m b/module/css.m
new file mode 100644
index 00000000..3c72d06f
--- /dev/null
+++ b/module/css.m
@@ -0,0 +1,88 @@
+#
+# CSS parsing module
+#
+# CSS2.1 style sheets
+#
+# Copyright © 2001, 2005 Vita Nuova Holdings Limited. All rights reserved.
+#
+CSS: module
+{
+ PATH: con "/dis/lib/w3c/css.dis";
+
+ Stylesheet: adt {
+ charset: string;
+ imports: list of ref Import;
+ statements: list of ref Statement;
+ };
+
+ Import: adt {
+ name: string;
+ media: list of string;
+ };
+
+ Statement: adt {
+ pick{
+ Media =>
+ media: list of string;
+ rules: list of ref Statement.Ruleset;
+ Page =>
+ pseudo: string;
+ decls: list of ref Decl;
+ Ruleset =>
+ selectors: list of Selector;
+ decls: list of ref Decl;
+ }
+ };
+
+ Decl: adt {
+ property: string;
+ values: list of ref Value;
+ important: int;
+ };
+
+ Selector: type list of (int, Simplesel); # int is combinator from [ >+]
+ Simplesel: type list of ref Select;
+
+ Select: adt {
+ name: string;
+ pick{
+ Element or ID or Any or Class or Pseudo =>
+ Attrib =>
+ op: string; # "=" "~=" "|="
+ value: ref Value; # optional Ident or String
+ Pseudofn =>
+ arg: string;
+ }
+ };
+
+ Value: adt {
+ sep: int; # which operator of [ ,/] preceded this value in list
+ pick{
+ String or
+ Number or
+ Percentage or
+ Url or
+ Unicoderange =>
+ value: string;
+ Hexcolour =>
+ value: string; # as given
+ rgb: (int, int, int); # converted
+ RGB =>
+ args: cyclic list of ref Value; # as given
+ rgb: (int, int, int); # converted
+ Ident =>
+ name: string;
+ Unit =>
+ value: string; # int or float
+ units: string; # suffix giving units ("cm", "khz", and so on, always lower case)
+ Function =>
+ name: string;
+ args: cyclic list of ref Value;
+ }
+ };
+
+ init: fn(diag: int);
+ parse: fn(s: string): (ref Stylesheet, string);
+ parsedecl: fn(s: string): (list of ref Decl, string);
+# unescape: fn(s: string): string;
+};
diff --git a/module/cvsimages.m b/module/cvsimages.m
new file mode 100644
index 00000000..7ff66ce8
--- /dev/null
+++ b/module/cvsimages.m
@@ -0,0 +1,14 @@
+Cvsimages: module {
+ PATH: con "/dis/lib/cvsimages.dis";
+ init: fn();
+ Cvsimage: adt {
+ new: fn(win: ref Tk->Toplevel, w: string): ref Cvsimage;
+ fix: fn(ci: self ref Cvsimage);
+ config: fn(ci: self ref Cvsimage): int;
+
+ image: ref Draw->Image;
+ win: ref Tk->Toplevel;
+ w: string;
+ r: Draw->Rect;
+ };
+};
diff --git a/module/daytime.m b/module/daytime.m
new file mode 100644
index 00000000..e1607ad9
--- /dev/null
+++ b/module/daytime.m
@@ -0,0 +1,53 @@
+Daytime: module
+{
+ PATH: con "/dis/lib/daytime.dis";
+
+ Tm: adt {
+ sec: int; # seconds (0 to 59)
+ min: int; # minutes (0 to 59)
+ hour: int; # hours (0 to 23)
+ mday: int; # day of the month (1 to 31)
+ mon: int; # month (0 to 11)
+ year: int; # year-1900; 2000AD is 100
+ wday: int; # day of week (0 to 6, Sunday is 0)
+ yday: int; # day of year (0 to 365)
+ zone: string; # time zone name
+ tzoff: int; # time zone offset (seconds from GMT)
+ };
+
+ # now:
+ # return the time in seconds since the epoch
+ #
+ # time:
+ # return the current local time as string
+ #
+ # text:
+ # convert a time structure from local or gmt
+ # into a text string
+ #
+ # filet:
+ # return a string containing the file time
+ # prints mon day hh:mm if the file is < 6 months old
+ # mon day year if > 6 months old
+ #
+ # local:
+ # uses /locale/timezone to convert an epoch time in seconds into
+ # a local time structure
+ #
+ # gmt:
+ # return a time structure for GMT
+ #
+ # tm2epoch:
+ # convert a time structure to an epoch time in seconds
+ #
+ # string2tm:
+ # parse a string representing a date into a time structure
+ now: fn(): int;
+ time: fn(): string;
+ text: fn(tm: ref Tm): string;
+ filet: fn(now, file: int): string;
+ local: fn(tim: int): ref Tm;
+ gmt: fn(tim: int): ref Tm;
+ tm2epoch: fn(tm: ref Tm): int;
+ string2tm: fn(date: string): ref Tm;
+};
diff --git a/module/db.m b/module/db.m
new file mode 100644
index 00000000..986621f5
--- /dev/null
+++ b/module/db.m
@@ -0,0 +1,69 @@
+DB : module
+{
+ PATH : con "/dis/lib/db.dis";
+
+ # Open the connection to the DB server
+ # returns (New handle, "") or (nil, "Error Message")
+ #
+ open: fn(addr, username, password, dbname: string) :
+ (ref DB_Handle, list of string);
+ #
+ # Opens a connection to an Inferno on the database machine, with the
+ # specified level of security.
+ #
+ connect : fn(addr, alg : string) : (ref Sys->FD, string);
+ #
+ # Mounts the file descriptor on dir, then opens the database.
+ #
+ dbopen: fn(fd : ref Sys->FD, username, password, dbname : string) :
+ (ref DB_Handle, list of string);
+
+ DB_Handle : adt
+ {
+ #
+ # Open another SQL stream for the same connection.
+ #
+ SQLOpen : fn(oldh : self ref DB_Handle) : (int, ref DB_Handle);
+ SQLClose : fn(dbh : self ref DB_Handle) : int;
+
+ # Execute the SQL command
+ # returns (0, "") or (error code, "Message")
+ #
+ SQL: fn(handle: self ref DB_Handle, command: string)
+ : (int, list of string);
+
+ # Check the number of columns of last select command
+ #
+ columns: fn(handle: self ref DB_Handle): int;
+
+ # Fetch the next row of the selection results.
+ # returns current row number, or 0
+ #
+ nextRow: fn(handle: self ref DB_Handle): int;
+
+ # Read the data of column[i] of current row
+ #
+ read: fn(handle: self ref DB_Handle, column: int)
+ : (int, array of byte);
+
+ # Write data to be used for parameter[i]
+ #
+ write: fn(handle: self ref DB_Handle, column: int,
+ fieldval: array of byte) : int;
+
+ # Title of the column[i]
+ #
+ columnTitle: fn(handle: self ref DB_Handle, column: int)
+ : string;
+
+ #error message associated with last command
+ #
+ errmsg: fn(handle: self ref DB_Handle): string;
+
+ datafd : ref Sys->FD;
+ sqlconn:int;
+ sqlstream : int;
+ lock : chan of int;
+
+ };
+};
diff --git a/module/dbm.m b/module/dbm.m
new file mode 100755
index 00000000..17897fd0
--- /dev/null
+++ b/module/dbm.m
@@ -0,0 +1,35 @@
+Dbm: module
+{
+ PATH: con "/dis/lib/dbm.dis";
+
+ Datum: type array of byte;
+
+ Dbf: adt {
+ create: fn(file: string, perm: int): ref Dbf;
+ open: fn(file: string, flags: int): ref Dbf;
+
+ fetch: fn(db: self ref Dbf, key: Datum): Datum;
+ delete: fn(db: self ref Dbf, key: Datum): int;
+ store: fn(db: self ref Dbf, key: Datum, dat: Datum, replace: int): int;
+ firstkey: fn(db: self ref Dbf): Datum;
+ nextkey: fn(db: self ref Dbf, key: Datum): Datum;
+
+ flush: fn(db: self ref Dbf);
+
+ isrdonly: fn(db: self ref Dbf): int;
+
+ dirf: ref Sys->FD; # directory
+ pagf: ref Sys->FD; # page
+ flags: int;
+ maxbno: int; # last `bno' in page file
+ bitno: int;
+ hmask: int;
+ blkno: int; # current page to read/write
+ pagbno: int; # current page in pagbuf
+ pagbuf: array of byte; # [PBLKSIZ]
+ dirbno: int; # current block in dirbuf
+ dirbuf: array of byte; # [DBLKSIZ]
+ };
+
+ init: fn();
+};
diff --git a/module/debug.m b/module/debug.m
new file mode 100644
index 00000000..4abfe585
--- /dev/null
+++ b/module/debug.m
@@ -0,0 +1,116 @@
+Debug: module
+{
+ PATH: con "/dis/lib/debug.dis";
+
+ Terror, Tid, Tadt, Tadtpick, Tarray, Tbig, Tbyte, Tchan, Treal,
+ Tfn, Targ, Tlocal, Tglobal, Tint, Tlist, Tmodule, Tnil, Tnone,
+ Tref, Tstring, Ttuple, Tend, Targs, Tslice, Tpoly: con iota;
+
+ Pos: adt
+ {
+ file: string;
+ line: int; # line number: origin 1
+ pos: int; # character within the line: origin 0
+ };
+ Src: adt
+ {
+ start: Pos; # range within source files
+ stop: Pos;
+ };
+ Id: adt
+ {
+ src: ref Src;
+ name: string;
+ offset: int; # start of pc, offset in frame, etc
+ stoppc: int; # limit pc of function
+ t: cyclic ref Type;
+ };
+ Type: adt
+ {
+ src: ref Src;
+ kind: int;
+ size: int;
+ name: string; # for adts, modules
+ Of: cyclic ref Type; # for lists, arrays, etc.
+ ids: cyclic array of ref Id; # for adts, etc. locals for fns
+ tags: cyclic array of ref Type;# for adts with pick tags
+
+ text: fn(t: self ref Type, sym: ref Sym): string;
+ getkind: fn(t: self ref Type, sym: ref Sym): int;
+ };
+ Sym: adt
+ {
+ path: string;
+ name: string; # implements name
+ src: array of ref Src;
+ srcstmt: array of int;
+ adts: array of ref Type;
+ fns: array of ref Id;
+ vars: array of ref Id;
+
+ srctopc: fn(s: self ref Sym, src: ref Src): int;
+ pctosrc: fn(s: self ref Sym, pc: int): ref Src;
+ };
+
+ Module: adt
+ {
+ path: string; # from whence loaded
+ code: int; # address of code start
+ data: int; # address of data
+ comp: int; # compiled to native assembler?
+ sym: ref Sym;
+
+ addsym: fn(m: self ref Module, sym: ref Sym);
+ stdsym: fn(m: self ref Module);
+ dis: fn(m: self ref Module): string;
+ sbl: fn(m: self ref Module): string;
+ };
+
+ StepExp, StepStmt, StepOver, StepOut: con iota;
+ Prog: adt
+ {
+ id: int;
+ heap: ref Sys->FD; # prog heap file
+ ctl: ref Sys->FD; # prog control file
+ dbgctl: ref Sys->FD; # debug file
+ stk: ref Sys->FD; # stack file
+
+ status: fn(p: self ref Prog): (int, string, string, string);
+ stack: fn(p: self ref Prog): (array of ref Exp, string);
+ step: fn(p: self ref Prog, how: int): string;
+ cont: fn(p: self ref Prog): string;
+ grab: fn(p: self ref Prog): string;
+ start: fn(p: self ref Prog): string;
+ stop: fn(p: self ref Prog): string;
+ unstop: fn(p: self ref Prog): string;
+ kill: fn(p: self ref Prog): string;
+ event: fn(p: self ref Prog): string;
+ setbpt: fn(p: self ref Prog, dis: string, pc: int): string;
+ delbpt: fn(p: self ref Prog, dis: string, pc: int): string;
+ };
+
+ Exp: adt
+ {
+ name: string;
+ offset: int;
+ pc: int;
+ m: ref Module;
+ p: ref Prog;
+
+ # this is private
+ id: ref Id;
+
+ expand: fn(e: self ref Exp): array of ref Exp;
+ val: fn(e: self ref Exp): (string, int);
+ typename: fn(e: self ref Exp): string;
+ kind: fn(e: self ref Exp): int;
+ src: fn(e: self ref Exp): ref Src;
+ findsym:fn(e: self ref Exp): string;
+ srcstr: fn(e: self ref Exp): string;
+ };
+
+ init: fn(): int;
+ sym: fn(sbl: string): (ref Sym, string);
+ prog: fn(pid: int): (ref Prog, string);
+ startprog: fn(dis, dir: string, ctxt: ref Draw->Context, argv: list of string): (ref Prog, string);
+};
diff --git a/module/devpointer.m b/module/devpointer.m
new file mode 100644
index 00000000..ea7bb7a6
--- /dev/null
+++ b/module/devpointer.m
@@ -0,0 +1,21 @@
+Devpointer: module
+{
+ PATH: con "/dis/lib/devpointer.dis";
+
+ Size: con 1+4*12; # 'm' plus 4 12-byte decimal integers
+ # merge events that have the same button state.
+ Ptrqueue: adt {
+ last: ref Draw->Pointer;
+ h, t: list of ref Draw->Pointer;
+ put: fn(q: self ref Ptrqueue, s: ref Draw->Pointer);
+ get: fn(q: self ref Ptrqueue): ref Draw->Pointer;
+ peek: fn(q: self ref Ptrqueue): ref Draw->Pointer;
+ nonempty: fn(q: self ref Ptrqueue): int;
+ };
+
+ init: fn();
+ reader: fn(file: string, posn: chan of ref Draw->Pointer, pid: chan of (int, string));
+ bytes2ptr: fn(b: array of byte): ref Draw->Pointer;
+ ptr2bytes: fn(p: ref Draw->Pointer): array of byte;
+ srv: fn(c: chan of ref Draw->Pointer, f: ref Sys->FileIO);
+};
diff --git a/module/dhcp.m b/module/dhcp.m
new file mode 100644
index 00000000..a0c52c7f
--- /dev/null
+++ b/module/dhcp.m
@@ -0,0 +1,84 @@
+Dhcpclient: module
+{
+ PATH: con "/dis/lib/dhcpclient.dis";
+
+ Bootconf: adt {
+ ip: string;
+ ipgw: string;
+ ipmask: string;
+ bootf: string;
+ bootip: string;
+ dhcpip: string;
+ siaddr: string;
+ serverid: string;
+ sys: string;
+ dom: string;
+ lease: int;
+ options: array of array of byte;
+ vendor: array of array of byte;
+
+ new: fn(): ref Bootconf;
+ get: fn(c: self ref Bootconf, n: int): array of byte;
+ getint: fn(c: self ref Bootconf, n: int): int;
+ getip: fn(c: self ref Bootconf, n: int): string;
+ getips: fn(c: self ref Bootconf, n: int): list of string;
+ gets: fn(c: self ref Bootconf, n: int): string;
+ put: fn(c: self ref Bootconf, n: int, a: array of byte);
+ putint: fn(c: self ref Bootconf, n: int, v: int);
+ putips: fn(c: self ref Bootconf, n: int, ips: list of string);
+ puts: fn(c: self ref Bootconf, n: int, s: string);
+ };
+
+ Lease: adt {
+ pid: int;
+ configs: chan of (ref Bootconf, string);
+
+ release: fn(l: self ref Lease);
+ };
+
+ init: fn();
+ tracing: fn(debug: int);
+ bootp: fn(net: string, ctlifc: ref Sys->FD, device: string, init: ref Bootconf): (ref Bootconf, string);
+ dhcp: fn(net: string, ctlifc: ref Sys->FD, device: string, init: ref Bootconf, options: array of int): (ref Bootconf, ref Lease, string);
+
+ applycfg: fn(net: string, ctlifc: ref Sys->FD, conf: ref Bootconf): string;
+ removecfg: fn(net: string, ctlifc: ref Sys->FD, conf: ref Bootconf): string;
+
+ # bootp options used here
+ Opad: con 0;
+ Oend: con 255;
+ Omask: con 1;
+ Orouter: con 3;
+ Odnsserver: con 6;
+ Ocookieserver: con 8;
+ Ohostname: con 12;
+ Odomainname: con 15;
+ Ontpserver: con 42;
+ Ovendorinfo: con 43;
+ Onetbiosns: con 44;
+ Osmtpserver: con 69;
+ Opop3server: con 70;
+ Owwwserver: con 72;
+
+ # dhcp options
+ Oipaddr: con 50;
+ Olease: con 51;
+ Ooverload: con 52;
+ Otype: con 53;
+ Oserverid: con 54;
+ Oparams: con 55;
+ Omessage: con 56;
+ Omaxmsg: con 57;
+ Orenewaltime: con 58;
+ Orebindingtime: con 59;
+ Ovendorclass: con 60;
+ Oclientid: con 61;
+ Otftpserver: con 66;
+ Obootfile: con 67;
+
+ Ovendor: con (1<<8);
+ OP9fs: con Ovendor|128; # plan 9 file server
+ OP9auth: con Ovendor|129; # plan 9 auth server
+
+ Infinite: con ~0; # lease
+};
diff --git a/module/dialog.m b/module/dialog.m
new file mode 100644
index 00000000..befbaf8e
--- /dev/null
+++ b/module/dialog.m
@@ -0,0 +1,9 @@
+Dialog: module
+{
+ PATH: con "/dis/lib/dialog.dis";
+ init: fn(): string;
+
+ prompt: fn(ctxt: ref Draw->Context, parent: ref Draw->Image, ico, title, msg: string,
+ dflt: int, labs: list of string): int;
+ getstring: fn(ctxt: ref Draw->Context, parent: ref Draw->Image, msg: string): string;
+};
diff --git a/module/dict.m b/module/dict.m
new file mode 100644
index 00000000..c1262e6a
--- /dev/null
+++ b/module/dict.m
@@ -0,0 +1,14 @@
+Dictionary: module {
+ PATH: con "/dis/lib/dict.dis";
+
+ Dict: adt {
+ entries: list of (string, string);
+
+ add: fn( d: self ref Dict, e: (string, string) );
+ delete: fn( d: self ref Dict, k: string );
+ lookup: fn( d: self ref Dict, k: string ) :string;
+ keys: fn( d: self ref Dict ): list of string;
+ };
+
+
+}; \ No newline at end of file
diff --git a/module/dis.m b/module/dis.m
new file mode 100644
index 00000000..27b47dcc
--- /dev/null
+++ b/module/dis.m
@@ -0,0 +1,323 @@
+Dis: module
+{
+ PATH: con "/dis/lib/dis.dis";
+
+ XMAGIC: con 819248;
+ SMAGIC: con 923426;
+ MUSTCOMPILE: con 1<<0;
+ DONTCOMPILE: con 1<<1;
+ SHAREMP: con 1<<2;
+ DYNMOD: con 1<<3;
+ HASLDT0: con 1<<4;
+ HASEXCEPT: con 1<<5;
+ HASLDT: con 1<<6;
+
+ AMP: con 16r00; # Src/Dst op addressing
+ AFP: con 16r01;
+ AIMM: con 16r02;
+ AXXX: con 16r03;
+ AIND: con 16r04;
+ AMASK: con 16r07;
+
+ ARM: con 16rC0; # Middle op addressing
+ AXNON: con 16r00;
+ AXIMM: con 16r40;
+ AXINF: con 16r80;
+ AXINM: con 16rC0;
+
+ DEFZ: con 0;
+ DEFB: con 1; # Byte
+ DEFW: con 2; # Word
+ DEFS: con 3; # Utf-string
+ DEFF: con 4; # Real value
+ DEFA: con 5; # Array
+ DIND: con 6; # Set index
+ DAPOP: con 7; # Restore address register
+ DEFL: con 8; # BIG
+ DMAX: con 1<<4;
+
+ Inst: adt
+ {
+ op: int;
+ addr: int;
+ mid: int;
+ src: int;
+ dst: int;
+ };
+
+ Type: adt
+ {
+ size: int;
+ np: int;
+ map: array of byte;
+ };
+
+ Data: adt
+ {
+ op: int; # encoded op
+ n: int; # number of elements
+ off: int; # byte offset in data space
+ pick {
+ Zero => # DEFZ
+ Bytes => # DEFB
+ bytes: array of byte;
+ Words => # DEFW
+ words: array of int;
+ String => # DEFS
+ str: string;
+ Reals => # DEFF
+ reals: array of real;
+ Array => # DEFA
+ typex: int;
+ length: int;
+ Aindex => # DIND
+ index: int;
+ Arestore => # DAPOP
+ Bigs => # DEFL
+ bigs: array of big;
+ }
+ };
+
+ Link: adt
+ {
+ pc: int;
+ desc: int;
+ sig: int;
+ name: string;
+ };
+
+ Import: adt
+ {
+ sig: int;
+ name: string;
+ };
+
+ Except: adt
+ {
+ s: string;
+ pc: int;
+ };
+
+ Handler: adt
+ {
+ pc1: int;
+ pc2: int;
+ eoff: int;
+ ne: int;
+ t: ref Type;
+ etab: array of ref Except;
+ };
+
+ Mod: adt
+ {
+ name: string;
+ srcpath: string;
+
+ magic: int;
+ rt: int;
+ ssize: int;
+ isize: int;
+ dsize: int;
+ tsize: int;
+ lsize: int;
+ entry: int;
+ entryt: int;
+
+ inst: array of ref Inst;
+ types: array of ref Type;
+ data: list of ref Data;
+ links: array of ref Link;
+ imports: array of array of ref Import;
+ handlers: array of ref Handler;
+
+ sign: array of byte;
+ };
+
+ INOP,
+ IALT,
+ INBALT,
+ IGOTO,
+ ICALL,
+ IFRAME,
+ ISPAWN,
+ IRUNT,
+ ILOAD,
+ IMCALL,
+ IMSPAWN,
+ IMFRAME,
+ IRET,
+ IJMP,
+ ICASE,
+ IEXIT,
+ INEW,
+ INEWA,
+ INEWCB,
+ INEWCW,
+ INEWCF,
+ INEWCP,
+ INEWCM,
+ INEWCMP,
+ ISEND,
+ IRECV,
+ ICONSB,
+ ICONSW,
+ ICONSP,
+ ICONSF,
+ ICONSM,
+ ICONSMP,
+ IHEADB,
+ IHEADW,
+ IHEADP,
+ IHEADF,
+ IHEADM,
+ IHEADMP,
+ ITAIL,
+ ILEA,
+ IINDX,
+ IMOVP,
+ IMOVM,
+ IMOVMP,
+ IMOVB,
+ IMOVW,
+ IMOVF,
+ ICVTBW,
+ ICVTWB,
+ ICVTFW,
+ ICVTWF,
+ ICVTCA,
+ ICVTAC,
+ ICVTWC,
+ ICVTCW,
+ ICVTFC,
+ ICVTCF,
+ IADDB,
+ IADDW,
+ IADDF,
+ ISUBB,
+ ISUBW,
+ ISUBF,
+ IMULB,
+ IMULW,
+ IMULF,
+ IDIVB,
+ IDIVW,
+ IDIVF,
+ IMODW,
+ IMODB,
+ IANDB,
+ IANDW,
+ IORB,
+ IORW,
+ IXORB,
+ IXORW,
+ ISHLB,
+ ISHLW,
+ ISHRB,
+ ISHRW,
+ IINSC,
+ IINDC,
+ IADDC,
+ ILENC,
+ ILENA,
+ ILENL,
+ IBEQB,
+ IBNEB,
+ IBLTB,
+ IBLEB,
+ IBGTB,
+ IBGEB,
+ IBEQW,
+ IBNEW,
+ IBLTW,
+ IBLEW,
+ IBGTW,
+ IBGEW,
+ IBEQF,
+ IBNEF,
+ IBLTF,
+ IBLEF,
+ IBGTF,
+ IBGEF,
+ IBEQC,
+ IBNEC,
+ IBLTC,
+ IBLEC,
+ IBGTC,
+ IBGEC,
+ ISLICEA,
+ ISLICELA,
+ ISLICEC,
+ IINDW,
+ IINDF,
+ IINDB,
+ INEGF,
+ IMOVL,
+ IADDL,
+ ISUBL,
+ IDIVL,
+ IMODL,
+ IMULL,
+ IANDL,
+ IORL,
+ IXORL,
+ ISHLL,
+ ISHRL,
+ IBNEL,
+ IBLTL,
+ IBLEL,
+ IBGTL,
+ IBGEL,
+ IBEQL,
+ ICVTLF,
+ ICVTFL,
+ ICVTLW,
+ ICVTWL,
+ ICVTLC,
+ ICVTCL,
+ IHEADL,
+ ICONSL,
+ INEWCL,
+ ICASEC,
+ IINDL,
+ IMOVPC,
+ ITCMP,
+ IMNEWZ,
+ ICVTRF,
+ ICVTFR,
+ ICVTWS,
+ ICVTSW,
+ ILSRW,
+ ILSRL,
+ IECLR,
+ INEWZ,
+ INEWAZ,
+ IRAISE,
+ ICASEL,
+ IMULX,
+ IDIVX,
+ ICVTXX,
+ IMULX0,
+ IDIVX0,
+ ICVTXX0,
+ IMULX1,
+ IDIVX1,
+ ICVTXX1,
+ ICVTFX,
+ ICVTXF,
+ IEXPW,
+ IEXPL,
+ IEXPF,
+ ISELF,
+ # add new instructions here
+ MAXDIS: con iota;
+
+ init: fn();
+ loadobj: fn(file: string): (ref Mod, string);
+ op2s: fn(op: int): string;
+ inst2s: fn(ins: ref Inst): string;
+ src: fn(file: string): string;
+};
+#
+# derived by Vita Nuova Limited 1998 from /appl/wm/rt.b and /include/isa.h, both
+# Copyright © 1996-1999 Lucent Technologies Inc. All rights reserved.
+#
diff --git a/module/diskblocks.m b/module/diskblocks.m
new file mode 100644
index 00000000..44af5b22
--- /dev/null
+++ b/module/diskblocks.m
@@ -0,0 +1,26 @@
+Diskblocks: module {
+ PATH: con "/dis/lib/diskblocks.dis";
+
+ Block: adt {
+ addr: big; # address on file
+ n: int; # size in bytes
+ };
+
+ Disk: adt {
+ fd: ref Sys->FD;
+ addr: big; # length of temp file
+ free: array of list of ref Block;
+ maxblock: int;
+ gran: int;
+ lock: chan of int;
+
+ init: fn(fd: ref Sys->FD, gran: int, maxblock: int): ref Disk;
+ new: fn(d: self ref Disk, n: int): ref Block;
+ release: fn(d: self ref Disk, b: ref Block);
+ read: fn(d: self ref Disk, b: ref Block, a: array of byte, n: int): int;
+ write: fn(d: self ref Disk, b: ref Block, a: array of byte, n: int): ref Block;
+ };
+
+ init: fn();
+ tempfile: fn(): ref Sys->FD;
+};
diff --git a/module/disks.m b/module/disks.m
new file mode 100644
index 00000000..2063eef2
--- /dev/null
+++ b/module/disks.m
@@ -0,0 +1,55 @@
+#
+# adapted from /sys/include/disk.h on Plan 9: subject to the Lucent Public License 1.02
+#
+Disks: module
+{
+ PATH: con "/dis/lib/disks.dis";
+
+ # disk partition interface
+ Disk: adt {
+ prefix: string;
+ part: string;
+ fd: ref Sys->FD;
+ wfd: ref Sys->FD;
+ ctlfd: ref Sys->FD;
+ rdonly: int;
+ dtype: string; # "file", "sd" or "floppy"
+
+ secs: big;
+ secsize: int;
+ size: big;
+ offset: big; # within larger disk, perhaps
+ width: int; # of disk size in bytes as decimal string
+ c: int; # geometry: cyl, head, sectors
+ h: int;
+ s: int;
+ chssrc: string; # "part", "disk" or "guess"
+
+ open: fn(f: string, mode: int, noctl: int): ref Disk;
+ readn: fn(d: self ref Disk, buf: array of byte, n: int): int;
+ };
+
+ init: fn();
+ readn: fn(fd: ref Sys->FD, buf: array of byte, n: int): int;
+
+ # PC partition grot
+ PCpart: adt {
+ active: int; # Active or 0
+ ptype: int;
+ base: big; # base block address: 0 or first extended partition in chain
+ offset: big; # block offset from base to partition
+ size: big; # in sectors
+
+ extract: fn(a: array of byte, d: ref Disk): PCpart;
+ bytes: fn(p: self PCpart, d: ref Disk): array of byte;
+ };
+ Toffset: con 446; # offset of partition table in sector
+ TentrySize: con 2+2*3+4+4; # partition table entry size
+ NTentry: con 4; # number of table entries
+ Magic0: con 16r55;
+ Magic1: con 16rAA;
+ Active: con 16r80; # partition is active
+ Type9: con 16r39; # partition type used by Plan 9 and Inferno
+
+ chstext: fn(p: array of byte): string;
+};
diff --git a/module/dividers.m b/module/dividers.m
new file mode 100644
index 00000000..f14a6405
--- /dev/null
+++ b/module/dividers.m
@@ -0,0 +1,33 @@
+Dividers: module {
+ init: fn();
+ Divider: adt {
+ new: fn(win: ref Tk->Toplevel, w: string, wl: list of string, dir: int): (ref Divider, chan of string);
+ event: fn(d: self ref Divider, e: string);
+
+ # private from here.
+ win: ref Tk->Toplevel;
+ w: string;
+ state: ref DState;
+
+ dir: int; # NS or EW
+ widgets: array of ref DWidget;
+ canvsize: Draw->Point;
+ };
+
+ EW, NS: con iota;
+ PATH: con "/dis/lib/dividers.dis";
+
+ # private from here
+ DWidget: adt {
+ w: string;
+ r: Draw->Rect;
+ size: Draw->Point;
+ };
+
+ DState: adt {
+ dragdiv: int;
+ dy: int;
+ maxy, miny: int;
+ };
+
+};
diff --git a/module/draw.m b/module/draw.m
new file mode 100644
index 00000000..730e62ac
--- /dev/null
+++ b/module/draw.m
@@ -0,0 +1,298 @@
+Draw: module
+{
+ PATH: con "$Draw";
+
+ # predefined colors; pass to Display.color
+ Opaque: con int 16rFFFFFFFF;
+ Transparent: con int 16r00000000; # only useful for Display.newimage
+ Black: con int 16r000000FF;
+ White: con int 16rFFFFFFFF;
+ Red: con int 16rFF0000FF;
+ Green: con int 16r00FF00FF;
+ Blue: con int 16r0000FFFF;
+ Cyan: con int 16r00FFFFFF;
+ Magenta: con int 16rFF00FFFF;
+ Yellow: con int 16rFFFF00FF;
+ Grey: con int 16rEEEEEEFF;
+ Paleyellow: con int 16rFFFFAAFF;
+ Darkyellow: con int 16rEEEE9EFF;
+ Darkgreen: con int 16r448844FF;
+ Palegreen: con int 16rAAFFAAFF;
+ Medgreen: con int 16r88CC88FF;
+ Darkblue: con int 16r000055FF;
+ Palebluegreen: con int 16rAAFFFFFF;
+ Paleblue: con int 16r0000BBFF;
+ Bluegreen: con int 16r008888FF;
+ Greygreen: con int 16r55AAAAFF;
+ Palegreygreen: con int 16r9EEEEEFF;
+ Yellowgreen: con int 16r99994CFF;
+ Medblue: con int 16r000099FF;
+ Greyblue: con int 16r005DBBFF;
+ Palegreyblue: con int 16r4993DDFF;
+ Purpleblue: con int 16r8888CCFF;
+
+ Notacolor: con int 16rFFFFFF00;
+ Nofill: con Notacolor;
+
+ # end styles for line
+ Endsquare: con 0;
+ Enddisc: con 1;
+ Endarrow: con 2;
+
+ # flush control
+ Flushoff: con 0;
+ Flushon: con 1;
+ Flushnow: con 2;
+
+ # image backing store
+ Refbackup: con 0;
+ Refnone: con 1;
+
+ # compositing operators
+ SinD: con 1<<3;
+ DinS: con 1<<2;
+ SoutD: con 1<<1;
+ DoutS: con 1<<0;
+
+ S: con SinD|SoutD;
+ SoverD: con SinD|SoutD|DoutS;
+ SatopD: con SinD|DoutS;
+ SxorD: con SoutD|DoutS;
+
+ D: con DinS|DoutS;
+ DoverS: con DinS|DoutS|SoutD;
+ DatopS: con DinS|SoutD;
+ DxorS: con DoutS|SoutD;
+
+ Clear: con 0;
+
+ # Image channels descriptor
+ Chans: adt
+ {
+ desc: int; # descriptor packed into an int
+
+ # interpret standard channel string
+ mk: fn(s: string): Chans;
+ # standard printable form
+ text: fn(c: self Chans): string;
+ # equality
+ eq: fn(c: self Chans, d: Chans): int;
+ # bits per pixel
+ depth: fn(c: self Chans): int;
+ };
+
+ CRed, CGreen, CBlue, CGrey, CAlpha, CMap, CIgnore: con iota;
+
+ GREY1: con Chans((CGrey<<4) | 1);
+ GREY2: con Chans((CGrey<<4) | 2);
+ GREY4: con Chans((CGrey<<4) | 4);
+ GREY8: con Chans((CGrey<<4) | 8);
+ CMAP8: con Chans((CMap<<4) | 8);
+ RGB15: con Chans(((CIgnore<<4)|1)<<24 | ((CRed<<4)|5)<<16 | ((CGreen<<4)|5)<<8 | ((CBlue<<4)|5));
+ RGB16: con Chans(((CRed<<4)|5)<<16 | ((CGreen<<4)|6)<<8 | ((CBlue<<4)|5));
+ RGB24: con Chans(((CRed<<4)|8)<<16 | ((CGreen<<4)|8)<<8 | ((CBlue<<4)|8));
+ RGBA32: con Chans((((CRed<<4)|8)<<16 | ((CGreen<<4)|8)<<8 | ((CBlue<<4)|8))<<8 | ((CAlpha<<4)|8));
+ ARGB32: con Chans(((CAlpha<<4)|8)<<24 | ((CRed<<4)|8)<<16 | ((CGreen<<4)|8)<<8 | ((CBlue<<4)|8)); # stupid VGAs
+ XRGB32: con Chans(((CIgnore<<4)|8)<<24 | ((CRed<<4)|8)<<16 | ((CGreen<<4)|8)<<8 | ((CBlue<<4)|8)); # stupid VGAs
+
+ # Coordinate of a pixel on display
+ Point: adt
+ {
+ x: int;
+ y: int;
+
+ # arithmetic
+ add: fn(p: self Point, q: Point): Point;
+ sub: fn(p: self Point, q: Point): Point;
+ mul: fn(p: self Point, i: int): Point;
+ div: fn(p: self Point, i: int): Point;
+ # equality
+ eq: fn(p: self Point, q: Point): int;
+ # inside rectangle
+ in: fn(p: self Point, r: Rect): int;
+ };
+
+ # Rectangle of pixels on the display; min <= max
+ Rect: adt
+ {
+ min: Point; # upper left corner
+ max: Point; # lower right corner
+
+ # make sure min <= max
+ canon: fn(r: self Rect): Rect;
+ # extent
+ dx: fn(r: self Rect): int;
+ dy: fn(r: self Rect): int;
+ size: fn(r: self Rect): Point;
+ # equality
+ eq: fn(r: self Rect, s: Rect): int;
+ # intersection and clipping
+ Xrect: fn(r: self Rect, s: Rect): int;
+ inrect: fn(r: self Rect, s: Rect): int;
+ clip: fn(r: self Rect, s: Rect): (Rect, int);
+ contains: fn(r: self Rect, p: Point): int;
+ combine: fn(r: self Rect, s: Rect): Rect;
+ # arithmetic
+ addpt: fn(r: self Rect, p: Point): Rect;
+ subpt: fn(r: self Rect, p: Point): Rect;
+ inset: fn(r: self Rect, n: int): Rect;
+ };
+
+ # a picture; if made by Screen.newwindow, a window. always attached to a Display
+ Image: adt
+ {
+ # these data are local copies, but repl and clipr
+ # are monitored by the runtime and may be modified as desired.
+ r: Rect; # rectangle in data area, local coords
+ clipr: Rect; # clipping region
+ depth: int; # number of bits per pixel
+ chans: Chans;
+ repl: int; # whether data area replicates to tile the plane
+ display: ref Display; # where Image resides
+ screen: ref Screen; # nil if not window
+ iname: string;
+
+ # graphics operators
+ drawop: fn(dst: self ref Image, r: Rect, src: ref Image, matte: ref Image, p: Point, op: int);
+ draw: fn(dst: self ref Image, r: Rect, src: ref Image, matte: ref Image, p: Point);
+ gendrawop: fn(dst: self ref Image, r: Rect, src: ref Image, p0: Point, matte: ref Image, p1: Point, op: int);
+ gendraw: fn(dst: self ref Image, r: Rect, src: ref Image, p0: Point, matte: ref Image, p1: Point);
+ lineop: fn(dst: self ref Image, p0,p1: Point, end0,end1,radius: int, src: ref Image, sp: Point, op: int);
+ line: fn(dst: self ref Image, p0,p1: Point, end0,end1,radius: int, src: ref Image, sp: Point);
+ polyop: fn(dst: self ref Image, p: array of Point, end0,end1,radius: int, src: ref Image, sp: Point, op: int);
+ poly: fn(dst: self ref Image, p: array of Point, end0,end1,radius: int, src: ref Image, sp: Point);
+ bezsplineop: fn(dst: self ref Image, p: array of Point, end0,end1,radius: int, src: ref Image, sp: Point, op: int);
+ bezspline: fn(dst: self ref Image, p: array of Point, end0,end1,radius: int, src: ref Image, sp: Point);
+ fillpolyop: fn(dst: self ref Image, p: array of Point, wind: int, src: ref Image, sp: Point, op: int);
+ fillpoly: fn(dst: self ref Image, p: array of Point, wind: int, src: ref Image, sp: Point);
+ fillbezsplineop: fn(dst: self ref Image, p: array of Point, wind: int, src: ref Image, sp: Point, op: int);
+ fillbezspline: fn(dst: self ref Image, p: array of Point, wind: int, src: ref Image, sp: Point);
+ ellipseop: fn(dst: self ref Image, c: Point, a, b, thick: int, src: ref Image, sp: Point, op: int);
+ ellipse: fn(dst: self ref Image, c: Point, a, b, thick: int, src: ref Image, sp: Point);
+ fillellipseop: fn(dst: self ref Image, c: Point, a, b: int, src: ref Image, sp: Point, op: int);
+ fillellipse: fn(dst: self ref Image, c: Point, a, b: int, src: ref Image, sp: Point);
+ arcop: fn(dst: self ref Image, c: Point, a, b, thick: int, src: ref Image, sp: Point, alpha, phi: int, op: int);
+ arc: fn(dst: self ref Image, c: Point, a, b, thick: int, src: ref Image, sp: Point, alpha, phi: int);
+ fillarcop: fn(dst: self ref Image, c: Point, a, b: int, src: ref Image, sp: Point, alpha, phi: int, op: int);
+ fillarc: fn(dst: self ref Image, c: Point, a, b: int, src: ref Image, sp: Point, alpha, phi: int);
+ bezierop: fn(dst: self ref Image, a,b,c,d: Point, end0,end1,radius: int, src: ref Image, sp: Point, op: int);
+ bezier: fn(dst: self ref Image, a,b,c,d: Point, end0,end1,radius: int, src: ref Image, sp: Point);
+ fillbezierop: fn(dst: self ref Image, a,b,c,d: Point, wind:int, src: ref Image, sp: Point, op: int);
+ fillbezier: fn(dst: self ref Image, a,b,c,d: Point, wind:int, src: ref Image, sp: Point);
+ textop: fn(dst: self ref Image, p: Point, src: ref Image, sp: Point, font: ref Font, str: string, op: int): Point;
+ text: fn(dst: self ref Image, p: Point, src: ref Image, sp: Point, font: ref Font, str: string): Point;
+ textbgop: fn(dst: self ref Image, p: Point, src: ref Image, sp: Point, font: ref Font, str: string, bg: ref Image, bgp: Point, op: int): Point;
+ textbg: fn(dst: self ref Image, p: Point, src: ref Image, sp: Point, font: ref Font, str: string, bg: ref Image, bgp: Point): Point;
+ border: fn(dst: self ref Image, r: Rect, i: int, src: ref Image, sp: Point);
+ arrow: fn(a,b,c: int): int;
+ # direct access to pixels
+ readpixels: fn(src: self ref Image, r: Rect, data: array of byte): int;
+ writepixels: fn(dst: self ref Image, r: Rect, data: array of byte): int;
+ # publishing
+ name: fn(src: self ref Image, name: string, in: int): int;
+ # windowing
+ top: fn(win: self ref Image);
+ bottom: fn(win: self ref Image);
+ flush: fn(win: self ref Image, func: int);
+ origin: fn(win: self ref Image, log, scr: Point): int;
+ };
+
+ # a frame buffer, holding a connection to /dev/draw
+ Display: adt
+ {
+ image: ref Image; # holds the contents of the display
+ white: ref Image;
+ black: ref Image;
+ opaque: ref Image;
+ transparent: ref Image;
+
+ # allocate and start refresh slave
+ allocate: fn(dev: string): ref Display;
+ startrefresh: fn(d: self ref Display);
+ # attach to existing Screen
+ publicscreen: fn(d: self ref Display, id: int): ref Screen;
+ getwindow: fn(d: self ref Display, winname: string, screen: ref Screen, image: ref Image, backup: int): (ref Screen, ref Image);
+ # image creation
+ newimage: fn(d: self ref Display, r: Rect, chans: Chans, repl, color: int): ref Image;
+ color: fn(d: self ref Display, color: int): ref Image;
+ colormix: fn(d: self ref Display, c1: int, c2: int): ref Image;
+ rgb: fn(d: self ref Display, r, g, b: int): ref Image;
+ # attach to named Image
+ namedimage: fn(d: self ref Display, name: string): ref Image;
+ # I/O to files
+ open: fn(d: self ref Display, name: string): ref Image;
+ readimage: fn(d: self ref Display, fd: ref Sys->FD): ref Image;
+ writeimage: fn(d: self ref Display, fd: ref Sys->FD, i: ref Image): int;
+ # color map
+ rgb2cmap: fn(d: self ref Display, r, g, b: int): int;
+ cmap2rgb: fn(d: self ref Display, c: int): (int, int, int);
+ cmap2rgba: fn(d: self ref Display, c: int): int;
+ };
+
+ # a mapping between characters and pictures; always attached to a Display
+ Font: adt
+ {
+ name: string; # *default* or a file name (this may change)
+ height: int; # interline spacing of font
+ ascent: int; # distance from baseline to top
+ display: ref Display; # where Font resides
+
+ # read from file or construct from local description
+ open: fn(d: ref Display, name: string): ref Font;
+ build: fn(d: ref Display, name, desc: string): ref Font;
+ # string extents
+ width: fn(f: self ref Font, str: string): int;
+ bbox: fn(f: self ref Font, str: string): Rect;
+ };
+
+ # a collection of windows; always attached to a Display
+ Screen: adt
+ {
+ id: int; # for export when public
+ image: ref Image; # root of window tree
+ fill: ref Image; # picture to use when repainting
+ display: ref Display; # where Screen resides
+
+ # create; see also Display.publicscreen
+ allocate: fn(image, fill: ref Image, public: int): ref Screen;
+ # allocate a new window
+ newwindow: fn(screen: self ref Screen, r: Rect, backing: int, color: int): ref Image;
+ # raise or lower a group of windows
+ top: fn(screen: self ref Screen, wins: array of ref Image);
+ bottom: fn(screen: self ref Screen, wins: array of ref Image);
+ };
+
+ # the state of a pointer device, e.g. a mouse or stylus
+ Pointer: adt
+ {
+ buttons: int; # bits 1 2 4 ... represent state of buttons left to right; 1 means pressed
+ xy: Point; # position
+ msec: int; # millisecond time stamp
+ };
+
+ # graphics context
+ Context: adt
+ {
+ display: ref Display; # frame buffer on which windows reside
+ screen: ref Screen; # place to make windows (mux only)
+ wm: chan of (string, chan of (string, ref Wmcontext)); # connect to window manager
+ };
+
+ # connection to window manager for one or more windows (as Images)
+ Wmcontext: adt
+ {
+ kbd: chan of int; # incoming characters from keyboard
+ ptr: chan of ref Pointer; # incoming stream of mouse positions
+ ctl: chan of string; # commands from wm to application
+ wctl: chan of string; # commands from application to wm
+ images: chan of ref Image; # exchange of images
+ connfd: ref Sys->FD; # connection control
+ ctxt: ref Context;
+ };
+
+ # functions that don't fit well in any adt
+ setalpha: fn(c: int, a: int): int;
+ bytesperline: fn(r: Rect, d: int): int;
+ icossin: fn(deg: int): (int, int);
+ icossin2: fn(p: Point): (int, int);
+};
diff --git a/module/ecmascript.m b/module/ecmascript.m
new file mode 100644
index 00000000..27856d9a
--- /dev/null
+++ b/module/ecmascript.m
@@ -0,0 +1,334 @@
+ESHostobj: module
+{
+ #
+ # extensible interface for adding host objects
+ #
+ # any implementation must obey the rules of the interpreter.
+ # it is an error to return bogus values, and may cause
+ # the interpreter to crash.
+ #
+ # get/put must return/set the value of property in o
+ #
+ # canput and hasproperty return es->true or es->false
+ #
+ # defaultval must return a primitive (non-object) value.
+ # this means it can't return a String object, etc.
+ #
+ # call gets the caller's execution context in ex.
+ # the new this value is passed as an argument,
+ # but no new scopechain is allocated
+ # it returns a reference, which is typically just a value
+ #
+ # construct should make up a new object
+ #
+ get: fn(ex: ref Ecmascript->Exec, o: ref Ecmascript->Obj, property: string): ref Ecmascript->Val;
+ put: fn(ex: ref Ecmascript->Exec, o: ref Ecmascript->Obj, property: string, val: ref Ecmascript->Val);
+ canput: fn(ex: ref Ecmascript->Exec, o: ref Ecmascript->Obj, property: string): ref Ecmascript->Val;
+ hasproperty: fn(ex: ref Ecmascript->Exec, o: ref Ecmascript->Obj, property: string): ref Ecmascript->Val;
+ delete: fn(ex: ref Ecmascript->Exec, o: ref Ecmascript->Obj, property: string);
+ defaultval: fn(ex: ref Ecmascript->Exec, o: ref Ecmascript->Obj, tyhint: int): ref Ecmascript->Val;
+ call: fn(ex: ref Ecmascript->Exec, func, this: ref Ecmascript->Obj, args: array of ref Ecmascript->Val, eval: int): ref Ecmascript->Ref;
+ construct: fn(ex: ref Ecmascript->Exec, func: ref Ecmascript->Obj, args: array of ref Ecmascript->Val): ref Ecmascript->Obj;
+};
+
+#
+# calls to init and mkexec do the following
+# math->FPcontrol(0, Math->INVAL|Math->ZDIV|Math->OVFL|Math->UNFL|Math->INEX);
+#
+Ecmascript: module
+{
+ PATH: con "/dis/lib/ecmascript.dis";
+
+ #
+ # an execution context
+ #
+ Exec: adt
+ {
+ #
+ # well known glop
+ #
+ objproto: cyclic ref Obj;
+ funcproto: cyclic ref Obj;
+ strproto: cyclic ref Obj;
+ numproto: cyclic ref Obj;
+ boolproto: cyclic ref Obj;
+ arrayproto: cyclic ref Obj;
+ dateproto: cyclic ref Obj;
+ regexpproto: cyclic ref Obj;
+ errproto: cyclic ref Obj;
+ evlerrproto: cyclic ref Obj;
+ ranerrproto: cyclic ref Obj;
+ referrproto: cyclic ref Obj;
+ synerrproto: cyclic ref Obj;
+ typerrproto: cyclic ref Obj;
+ urierrproto: cyclic ref Obj;
+ interrproto: cyclic ref Obj;
+
+ global: cyclic ref Obj;
+ this: cyclic ref Obj;
+ scopechain: cyclic list of ref Obj;
+
+ error: string;
+ errval: cyclic ref Val;
+
+ #
+ # private, keep out
+ #
+ stack: cyclic array of ref Ref;
+ sp: int;
+ };
+
+ #
+ # must be called at the dawn of time
+ # returns error string
+ init: fn(): string;
+
+ #
+ # initialize a new global execution context
+ # if go is supplied, it's the global object
+ # if not, one is made up automatically
+ #
+ mkexec: fn(go: ref Obj): ref Exec;
+
+ #
+ # throw a runtime error
+ # msg ends up in ex.error, and an
+ # "ecmascript runtime error" is raised
+ #
+ RUNTIME: con "ecmascript runtime error";
+ runtime: fn(ex: ref Exec, o: ref Obj, msg: string);
+
+ # runtime errors
+ EvalError, RangeError, ReferenceError, SyntaxError, TypeError, URIError, InternalError: ref Obj;
+
+ #
+ # debug flags: array of 256 indexed by char
+ #
+ # e print ops as they are executed
+ # f abort on an internal error
+ # p print parsed code
+ # r abort on any runtime error
+ # v print value of expression statements
+ #
+ debug: array of int;
+
+ #
+ # parse and runt the source string
+ #
+ eval: fn(ex: ref Exec, src: string): Completion;
+
+ Re: type ref Arena;
+
+ # the fundamental data structure
+ Obj: adt
+ {
+ props: cyclic array of ref Prop;
+ prototype: cyclic ref Obj; # some builtin properties
+ val: cyclic ref Val;
+ call: cyclic ref Call;
+ construct: cyclic ref Call;
+ class: string;
+ host: ESHostobj; # method suite for host objects
+ re: Re; # compiled regexp for RegExp objects
+ };
+
+ Call: adt
+ {
+ params: array of string;
+ code: cyclic ref Code;
+ ex: cyclic ref Exec;
+ };
+
+ # attributes
+ ReadOnly, DontEnum, DontDelete: con 1 << iota;
+ Prop: adt
+ {
+ attr: int;
+ name: string;
+ val: cyclic ref RefVal;
+ };
+
+ # an extra level of indirection, because sometimes properties are aliased
+ RefVal: adt
+ {
+ val: cyclic ref Val;
+ };
+
+ # types of js values
+ TUndef, TNull, TBool, TNum, TStr, TObj, TRegExp, NoHint: con iota;
+ Val: adt
+ {
+ ty: int;
+ num: real;
+ str: string;
+ obj: cyclic ref Obj;
+ rev: ref REval;
+ };
+
+ # regular expression
+ REval: adt
+ {
+ p: string;
+ f: string;
+ i: int;
+ };
+
+ # intermediate result of expression evaluation
+ Ref: adt
+ {
+ isref: int;
+ val: ref Val;
+ base: ref Obj;
+ name: string; # name of property within base
+ };
+
+ # completion values of statements
+ CNormal, CBreak, CContinue, CReturn, CThrow: con iota;
+ Completion: adt
+ {
+ kind: int;
+ val: ref Val;
+ lab: string;
+ };
+
+ Code: adt
+ {
+ ops: array of byte; # all instructions
+ npc: int; # end of active portion of ops
+ vars: cyclic array of ref Prop; # variables defined in the code
+ ids: array of string; # ids used in the code
+ strs: array of string; # string literal
+ nums: array of real; # numerical literals
+ fexps: cyclic array of ref Obj; # function expressions
+ };
+
+ #
+ # stuff for adding host objects
+ #
+ # ecmascript is also a host object;
+ get: fn(ex: ref Ecmascript->Exec, o: ref Ecmascript->Obj, property: string): ref Ecmascript->Val;
+ put: fn(ex: ref Ecmascript->Exec, o: ref Ecmascript->Obj, property: string, val: ref Ecmascript->Val);
+ canput: fn(ex: ref Ecmascript->Exec, o: ref Ecmascript->Obj, property: string): ref Ecmascript->Val;
+ hasproperty: fn(ex: ref Ecmascript->Exec, o: ref Ecmascript->Obj, property: string): ref Ecmascript->Val;
+ delete: fn(ex: ref Ecmascript->Exec, o: ref Ecmascript->Obj, property: string);
+ defaultval: fn(ex: ref Ecmascript->Exec, o: ref Ecmascript->Obj, tyhint: int): ref Ecmascript->Val;
+ call: fn(ex: ref Ecmascript->Exec, func, this: ref Ecmascript->Obj, args: array of ref Ecmascript->Val, eval: int): ref Ecmascript->Ref;
+ construct: fn(ex: ref Ecmascript->Exec, func: ref Ecmascript->Obj, args: array of ref Ecmascript->Val): ref Ecmascript->Obj;
+
+ #
+ # return the named variable from the scope chain sc
+ #
+ bivar: fn(ex: ref Exec, sc: list of ref Obj, s: string): ref Val;
+
+ #
+ # return the nth argument value, or undefined if too far
+ #
+ biarg: fn(args: array of ref Val, n: int): ref Val;
+
+ #
+ # make up a new object
+ # most often called as mkobj(ex.objproto, "Object")
+ #
+ mkobj: fn(proto: ref Obj, class: string): ref Obj;
+
+ #
+ # object installation helpers
+ #
+ Builtin: adt
+ {
+ name: string;
+ val: string;
+ params: array of string;
+ length: int;
+ };
+ biinst: fn(o: ref Obj, bi: Builtin, proto: ref Obj, h: ESHostobj): ref Obj;
+ biminst: fn(o: ref Obj, bis: array of Builtin, proto: ref Obj, h: ESHostobj);
+
+ #
+ # instantiate a new variable inside an object
+ #
+ varinstant: fn(in: ref Obj, attr: int, name: string, val: ref RefVal);
+
+ #
+ # various constructors
+ #
+ objval: fn(o: ref Obj): ref Val;
+ strval: fn(s: string): ref Val;
+ numval: fn(r: real): ref Val;
+ valref: fn(v: ref Val): ref Ref;
+
+ #
+ # conversion routines defined in section 9
+ #
+ toPrimitive: fn(ex: ref Exec, v: ref Val, ty: int): ref Val;
+ toBoolean: fn(ex: ref Exec, v: ref Val): ref Val;
+ toNumber: fn(ex: ref Exec, v: ref Val): real;
+ toInteger: fn(ex: ref Exec, v: ref Val): real;
+ toInt32: fn(ex: ref Exec, v: ref Val): int;
+ toUint32: fn(ex: ref Exec, v: ref Val): big;
+ toUint16: fn(ex: ref Exec, v: ref Val): int;
+ toString: fn(ex: ref Exec, v: ref Val): string;
+ toObject: fn(ex: ref Exec, v: ref Val): ref Obj;
+
+ #
+ # simple coercion routines to force
+ # Boolean, String, and Number values to objects and vice versa
+ #
+ coerceToObj: fn(ex: ref Exec, v: ref Val): ref Val;
+ coerceToVal: fn(v: ref Val): ref Val;
+
+ #
+ # object/value kind checkers
+ #
+ isstrobj: fn(o: ref Obj): int;
+ isnumobj: fn(o: ref Obj): int;
+ isboolobj: fn(o: ref Obj): int;
+ isdateobj: fn(o: ref Obj): int;
+ isregexpobj: fn(o: ref Obj): int;
+ isarray: fn(o: ref Obj): int;
+ isstr: fn(v: ref Val): int;
+ isnum: fn(v: ref Val): int;
+ isbool: fn(v: ref Val): int;
+ isobj: fn(v: ref Val): int;
+
+ #
+ # well-known ecmascript primitive values
+ #
+ undefined: ref Val;
+ true: ref Val;
+ false: ref Val;
+ null: ref Val;
+
+ # regexp data structures
+
+ refRex: type int; # used instead of ref Rex to avoid circularity
+
+ Set: adt { # character class
+ neg: int; # 0 or 1
+ ascii: array of int; # ascii members, bit array
+ unicode: list of (int,int); # non-ascii char ranges
+ subset: cyclic list of ref Set;
+ };
+
+ Nstate: adt{
+ m: int;
+ n: int;
+ };
+
+ Rex: adt { # node in parse of regex, or state of fsm
+ kind: int; # kind of node: char or ALT, CAT, etc
+ left: refRex; # left descendant
+ right: refRex; # right descendant, or next state
+ set: ref Set; # character class
+ pno: int;
+ greedy: int;
+ ns: ref Nstate;
+ };
+
+ Arena: adt { # free store from which nodes are allocated
+ rex: array of Rex;
+ ptr: refRex; # next available space
+ start: refRex; # root of parse, or start of fsm
+ pno: int;
+ };
+};
diff --git a/module/emio.m b/module/emio.m
new file mode 100644
index 00000000..e57d0476
--- /dev/null
+++ b/module/emio.m
@@ -0,0 +1,103 @@
+#
+# File: emio.m
+#
+# This file contains the declaration of the EMIO module.
+# The EMIO module provides protocol independent access
+# to an email server.
+#
+
+EMIO : module
+{
+ #
+ # The init function initializes the EMIO module.
+ # It must be called before any other function in the
+ # module.
+ #
+ init: fn();
+
+ #
+ # The open function opens a connection with the email
+ # server. The function requires the email server's
+ # tcp/ip address, a username and a password to make the
+ # connection to the email server. It returns a tuple
+ # (int, string). The int indicates success or failure
+ # (0 = failure, 1 = success). If the function fails,
+ # the int returned is 0, the string returned will indicate
+ # why the function failed. It should be called after the
+ # init function and before any other function in the module.
+ #
+ open: fn(ipaddr : string,
+ username : string,
+ password : string) : (int, string);
+
+ #
+ # The numberofmessages function indicates how many mail
+ # messages are in the specified users mailbox. It returns
+ # a tuple (int, string). The int indicates the number of
+ # mail messages in the mailbox (-1 = function failed, 0 =
+ # no mail message, 1 = one mail message ...). If the function fails,
+ # the int returned is -1, the string returned will indicate
+ # why the function failed.
+ #
+ numberofmessages: fn() : (int, string);
+
+ #
+ # This function provides the number of octets in the specified
+ # message number. It returns a tuple (int, string). The int indicates
+ # the number of octets in the mail message. If it is -1, the
+ # function has failed and the string returned will contain the
+ # possible reason.
+ # This function implements the LIST command, but only with an
+ # argument - the message number.
+ messagelength: fn(num : int) : (int, string);
+
+ #
+ # The messagetext function returns the text of the specified
+ # mail message. The function requires the number of the
+ # mail message to retrieve. It returns a triple
+ # (int, string, list of string). The int indicates success or failure
+ # (0 = failure, 1 = success). If the function fails,
+ # the int returned is 0, the string returned will indicate
+ # why the function failed. If the function succeded the list
+ # of string contains the text for the specified mail message.
+ #
+ messagetext: fn(messagenumber : int) : (int, string, list of string);
+
+ #
+ # This is similar to messagetext() but returns a string, rather than
+ # a list of string. The string contains the complete text of the mail
+ # message, header and body. Each line of the message is separate by a
+ # DELIMETER (currently set to |&|) fo easier processing.
+ #
+ msgtextstring: fn (num : int) : (int, string, string);
+
+ #
+ # The deletemessage function markes the specified mail
+ # message as deleted. The function requires the number of
+ # the mail message to delete. It returns a tuple
+ # (int, string). The int indicates success or failure
+ # (0 = failure, 1 = success). If the function fails,
+ # the int returned is 0, the string returned will indicate
+ # why the function failed.
+ #
+ deletemessage: fn(messagenumber : int) : (int, string);
+
+ #
+ # The reset function unmarks all messages that have been
+ # marked deleted during this session. It returns a tuple
+ # (int, string). The int indicates success or failure
+ # (0 = failure, 1 = success). If the function fails,
+ # the int returned is 0, the string returned will indicate
+ # why the function failed.
+ #
+ reset: fn() : (int, string);
+
+ #
+ # The close function closes a connection with the email
+ # server. It returns a tuple (int, string). The int
+ # indicates success or failure (0 = failure, 1 = success).
+ # If the function fails, the int returned is 0, the string
+ # returned will indicate why the function failed.
+ #
+ close: fn() : (int, string);
+};
diff --git a/module/encoding.m b/module/encoding.m
new file mode 100644
index 00000000..d70f9671
--- /dev/null
+++ b/module/encoding.m
@@ -0,0 +1,11 @@
+Encoding: module
+{
+ BASE64PATH: con "/dis/lib/encoding/base64.dis";
+ BASE32PATH: con "/dis/lib/encoding/base32.dis";
+ BASE32APATH: con "/dis/lib/encoding/base32a.dis";
+ BASE16PATH: con "/dis/lib/encoding/base16.dis";
+
+ enc: fn(a: array of byte): string;
+ dec: fn(s: string): array of byte;
+# deca: fn(a: array of byte): array of byte;
+};
diff --git a/module/env.m b/module/env.m
new file mode 100644
index 00000000..cfa113a3
--- /dev/null
+++ b/module/env.m
@@ -0,0 +1,10 @@
+Env: module {
+ getenv: fn(var: string): string; # returns nil if var not set
+ setenv: fn(var: string, val: string): int; # returns -1 on failure
+ getall: fn(): list of (string, string);
+
+ clone: fn(): int; # forks a copy of the environment, returns -1 on failure
+ new: fn(): int; # sets up new empty environment, returns -1 on failure
+
+ PATH: con "/dis/lib/env.dis";
+};
diff --git a/module/ether.m b/module/ether.m
new file mode 100644
index 00000000..a68f8c7b
--- /dev/null
+++ b/module/ether.m
@@ -0,0 +1,11 @@
+Ether: module
+{
+ PATH: con "/dis/lib/ether.dis";
+ Eaddrlen: con 6;
+
+ init: fn();
+ parse: fn(s: string): array of byte;
+ text: fn(a: array of byte): string;
+ addressof: fn(dev: string): array of byte;
+ eqaddr: fn(a, b: array of byte): int;
+};
diff --git a/module/exception.m b/module/exception.m
new file mode 100644
index 00000000..c5cf01ed
--- /dev/null
+++ b/module/exception.m
@@ -0,0 +1,18 @@
+Exception: module{
+
+ PATH: con "/dis/lib/exception.dis";
+
+ # returns the last exception in the form pc, module, exception
+ # on the process with the given pid (-1 gives current process)
+ # returns (0, nil, nil) if no exception
+ getexc: fn(pid: int): (int, string, string);
+
+ NOTIFYLEADER, PROPAGATE: con iota;
+
+ # set the exception mode(NOTIFYLEADER or PROPAGATE)
+ # on the current process
+ # it is assumed that the process is a group leader (see Sys->NEWPGRP)
+ # returns -1 on failure, 0 on success
+ setexcmode: fn(mode: int): int;
+
+};
diff --git a/module/factotum.m b/module/factotum.m
new file mode 100644
index 00000000..6dd98d93
--- /dev/null
+++ b/module/factotum.m
@@ -0,0 +1,36 @@
+Factotum: module
+{
+ PATH: con "/dis/lib/factotum.dis";
+
+ # client interface to Plan 9 or Inferno factotum
+
+ Authinfo: adt {
+ cuid: string; # caller id
+ suid: string; # server id
+ cap: string; # capability (only valid on server side)
+ secret: array of byte;
+
+ unpack: fn(a: array of byte): (int, ref Authinfo);
+ read: fn(fd: ref Sys->FD): ref Authinfo;
+ };
+
+ mount: fn(fd: ref Sys->FD, mnt: string, flags: int, aname: string, keyspec: string): (int, ref Authinfo);
+
+ # factotum interaction
+ AuthRpcMax: con 4096;
+
+ init: fn();
+ rpc: fn(fd: ref Sys->FD, verb: string, a: array of byte): (string, array of byte);
+ proxy: fn(afd: ref Sys->FD, facfd: ref Sys->FD, arg: string): ref Authinfo;
+ genproxy: fn(
+ readc: chan of (array of byte, chan of (int, string)),
+ writec: chan of (array of byte, chan of (int, string)),
+ donec: chan of (ref Authinfo, string),
+ afd: ref Sys->FD,
+ params: string);
+
+ getuserpasswd: fn(keyspec: string): (string, string);
+
+ dump: fn(a: array of byte): string;
+ setdebug: fn(i: int);
+};
diff --git a/module/ffts.m b/module/ffts.m
new file mode 100644
index 00000000..67b55607
--- /dev/null
+++ b/module/ffts.m
@@ -0,0 +1,32 @@
+FFTs: module{
+ PATH: con "/dis/math/ffts.dis";
+
+ ffts: fn(a,b:array of real, ntot,n,nspan,isn:int);
+};
+
+# multivariate complex fourier transform, computed in place
+# using mixed-radix fast fourier transform algorithm.
+# arrays a and b originally hold the real and imaginary
+# components of the data, and return the real and
+# imaginary components of the resulting fourier coefficients.
+# multivariate data is indexed according to the fortran
+# array element successor function, without limit
+# on the number of implied multiple subscripts.
+# the subroutine is called once for each variate.
+# the calls for a multivariate transform may be in any order.
+# ntot is the total number of complex data values.
+# n is the dimension of the current variable.
+# nspan/n is the spacing of consecutive data values
+# while indexing the current variable.
+# the sign of isn determines the sign of the complex
+# exponential, and the magnitude of isn is normally one.
+# univariate transform:
+# ffts(a,b,n,n,n,1)
+# trivariate transform with a(n1,n2,n3), b(n1,n2,n3):
+# ffts(a,b,n1*n2*n3,n1,n1,1)
+# ffts(a,b,n1*n2*n3,n2,n1*n2,1)
+# ffts(a,b,n1*n2*n3,n3,n1*n2*n3,1)
+# the data can alternatively be stored in a single vector c
+# alternating real and imaginary parts. the magnitude of isn changed
+# to two to give correct indexing increment, and a[0:] and a[1:] used
+# for a and b
diff --git a/module/filepat.m b/module/filepat.m
new file mode 100644
index 00000000..9d7dcd5b
--- /dev/null
+++ b/module/filepat.m
@@ -0,0 +1,10 @@
+Filepat: module
+{
+ PATH: con "/dis/lib/filepat.dis";
+
+ # Turn file name with * ? [] into list of files. Slashes are significant.
+ expand: fn(pat: string): list of string;
+
+ # See if file name matches pattern; slashes not treated specially.
+ match: fn(pat, name: string): int;
+};
diff --git a/module/filter.m b/module/filter.m
new file mode 100644
index 00000000..bd9fdb5a
--- /dev/null
+++ b/module/filter.m
@@ -0,0 +1,25 @@
+Filter: module
+{
+ DEFLATEPATH: con "/dis/lib/deflate.dis";
+ INFLATEPATH: con "/dis/lib/inflate.dis";
+ SLIPPATH: con "/dis/lib/slip.dis";
+
+ Rq: adt {
+ pick {
+ Start =>
+ pid: int;
+ Fill or Result =>
+ buf: array of byte;
+ reply: chan of int;
+ Info =>
+ msg: string;
+ Finished =>
+ buf: array of byte;
+ Error =>
+ e: string;
+ }
+ };
+
+ init: fn();
+ start: fn(param: string): chan of ref Rq;
+};
diff --git a/module/format.m b/module/format.m
new file mode 100644
index 00000000..1f3bfab6
--- /dev/null
+++ b/module/format.m
@@ -0,0 +1,30 @@
+Format: module {
+ PATH: con "/dis/lib/format.dis";
+ Fmtspec: adt {
+ name: string;
+ fields: cyclic array of Fmtspec;
+ };
+ Fmt: adt {
+ kind: int;
+ fields: cyclic array of Fmt;
+ };
+ Fmtval: adt {
+ val: ref Sexprs->Sexp;
+ recs: cyclic array of array of Fmtval;
+
+ text: fn(v: self Fmtval): string;
+ };
+ Fmtfile: adt {
+ spec: array of Fmtspec;
+ descr: array of byte;
+
+ new: fn(spec: array of Fmtspec): Fmtfile;
+ open: fn(f: self Fmtfile, name: string): ref Bufio->Iobuf;
+ read: fn(f: self Fmtfile, iob: ref Bufio->Iobuf): (array of Fmtval, string);
+ };
+ init: fn();
+ spec2se: fn(spec: array of Fmtspec): list of ref Sexprs->Sexp;
+ spec2fmt: fn(spec: array of Fmtspec): array of Fmt;
+ se2fmt: fn(spec: array of Fmtspec, se: ref Sexprs->Sexp): (array of Fmt, string);
+ rec2val: fn(spec: array of Fmtspec, rec: ref Sexprs->Sexp): (array of Fmtval, string);
+};
diff --git a/module/freetype.m b/module/freetype.m
new file mode 100644
index 00000000..ce4d5c4b
--- /dev/null
+++ b/module/freetype.m
@@ -0,0 +1,44 @@
+Freetype: module {
+ PATH: con "$Freetype";
+
+ Matrix: adt {
+ a, b: int; # 16.16 fixed-point coefficients
+ c, d: int;
+ };
+
+ Vector: adt {
+ dx: int; # 26.6 fixed-point deltas
+ dy: int;
+ };
+
+ STYLE_ITALIC,
+ STYLE_BOLD: con 1 << iota;
+
+ Face: adt {
+ nfaces: int;
+ index: int;
+ style: int; # STYLE_xxx
+ height: int;
+ ascent: int;
+ familyname: string;
+ stylename: string;
+
+ # pts - point size as a 26.6 fixed-point value
+ setcharsize: fn(face: self ref Face, pts, hdpi, vdpi: int): string;
+ settransform: fn(face: self ref Face, m: ref Matrix, v: ref Vector): string;
+ haschar: fn(face: self ref Face, c: int): int;
+ loadglyph: fn(face: self ref Face, c: int): ref Glyph;
+ };
+
+ Glyph: adt {
+ top: int;
+ left: int;
+ height: int;
+ width: int;
+ advance: Draw->Point; # 26.6 fixed-point
+ bitmap: array of byte; # (width*height) 8-bit greyscale
+ };
+
+ newface: fn(path: string, index: int): ref Face;
+ newmemface: fn(data: array of byte, index: int): ref Face;
+};
diff --git a/module/fslib.m b/module/fslib.m
new file mode 100644
index 00000000..79d90112
--- /dev/null
+++ b/module/fslib.m
@@ -0,0 +1,88 @@
+Fslib: module {
+ PATH: con "/dis/lib/fslib.dis";
+ Value: adt {
+ x: fn(v: self ref Value): ref Value.X;
+ p: fn(v: self ref Value): ref Value.P;
+ s: fn(v: self ref Value): ref Value.S;
+ c: fn(v: self ref Value): ref Value.C;
+ t: fn(v: self ref Value): ref Value.T;
+ v: fn(v: self ref Value): ref Value.V;
+ m: fn(v: self ref Value): ref Value.M;
+ typec: fn(v: self ref Value): int;
+ discard: fn(v: self ref Value);
+ pick {
+ X =>
+ i: Fschan;
+ T =>
+ i: Entrychan;
+ P =>
+ i: Gatechan;
+ C =>
+ i: ref Sh->Cmd;
+ S =>
+ i: string;
+ V =>
+ i: chan of int; # sync channel for void-valued processes
+ M =>
+ i: Cmpchan;
+ }
+ };
+ init: fn();
+ typecompat: fn(t, act: string): int;
+ sendnulldir: fn(c: Fschan): int;
+ quit: fn(errorc: chan of string);
+ report: fn(errorc: chan of string, err: string);
+ copy: fn(src, dst: Fschan): int;
+
+ cmdusage: fn(cmd, t: string): string;
+ type2s: fn(t: int): string;
+ opttypes: fn(opt: int, opts: string): (int, string);
+ splittype: fn(t: string): (int, string, string);
+
+ Report: adt {
+
+ reportc: chan of string;
+ startc: chan of (string, chan of string);
+ enablec: chan of int;
+
+ new: fn(): ref Report;
+ enable: fn(r: self ref Report);
+ start: fn(r: self ref Report, name: string): chan of string;
+ };
+ Option: adt {
+ opt: int;
+ args: list of ref Value;
+ };
+ Entrychan: adt {
+ sync: chan of int;
+ c: chan of Entry;
+ };
+ Cmpchan: type chan of (ref Sys->Dir, ref Sys->Dir, chan of int);
+ Entry: type (ref Sys->Dir, string, int);
+ Gatequery: type (Entry, chan of int);
+ Gatechan: type chan of Gatequery;
+ Fsdata: adt {
+ dir: ref Sys->Dir;
+ data: array of byte;
+ };
+ Fschan: type chan of (Fsdata, chan of int);
+ Next, Down, Skip, Quit: con iota;
+
+ Nilentry: con (nil, nil, 0);
+};
+
+Fsmodule: module {
+ types: fn(): string;
+ init: fn();
+ run: fn(ctxt: ref Draw->Context, r: ref Fslib->Report,
+ opts: list of Fslib->Option, args: list of ref Fslib->Value): ref Fslib->Value;
+};
+
+Fsfilter: module {
+ PATH: con "/dis/lib/fsfilter.dis";
+ filter: fn[T](t: T, src, dst: Fslib->Fschan)
+ for{
+ T =>
+ query: fn(t: self T, d: ref Sys->Dir, name: string, depth: int): int;
+ };
+};
diff --git a/module/fsproto.m b/module/fsproto.m
new file mode 100644
index 00000000..26bbaa56
--- /dev/null
+++ b/module/fsproto.m
@@ -0,0 +1,10 @@
+FSproto: module
+{
+ PATH: con "/dis/lib/fsproto.dis";
+
+ Direntry: type (string, string, ref Sys->Dir);
+
+ init: fn(): string;
+ readprotofile: fn(proto: string, root: string, entries: chan of Direntry, warnings: chan of (string, string)): string;
+ readprotostring: fn(proto: string, root: string, entries: chan of Direntry, warnings: chan of (string, string));
+};
diff --git a/module/gamer.m b/module/gamer.m
new file mode 100644
index 00000000..0494b1d6
--- /dev/null
+++ b/module/gamer.m
@@ -0,0 +1,16 @@
+Gamer: module
+{
+ PATH: con "/dis/lib/gamer.dis";
+
+ Game: adt {
+ rf, wf: ref Sys->FD;
+ opponent: string;
+ player: int;
+
+ In: fn(g: self Game) : int;
+ Out: fn(g: self Game, i: int);
+ Exit: fn(g: self Game);
+ };
+
+ Join: fn(game: string) : Game;
+};
diff --git a/module/gr.m b/module/gr.m
new file mode 100644
index 00000000..9227fbf6
--- /dev/null
+++ b/module/gr.m
@@ -0,0 +1,51 @@
+GR: module{
+ PATH: con "/dis/math/gr.dis";
+
+ OP: adt{
+ code, n: int;
+ x, y: array of real;
+ t: string;
+ };
+
+ open: fn(ctxt: ref Draw->Context, title: string): ref Plot;
+
+ Plot: adt{
+ bye: fn(p: self ref Plot);
+ equalxy:fn(p: self ref Plot);
+ graph: fn(p: self ref Plot, x, y: array of real);
+ paint: fn(p: self ref Plot, xlabel, xunit, ylabel, yunit: string);
+ pen: fn(p: self ref Plot, nib: int);
+ text: fn(p: self ref Plot, justify: int, s: string, x, y: real);
+
+ op: list of OP;
+ xmin, xmax, ymin, ymax: real;
+ textsize: real;
+ t: ref Tk->Toplevel; # window containing .fc.c canvas
+ titlechan: chan of string; # Wm titlebar
+ canvaschan: chan of string; # button clicks for measurements
+ };
+
+ # op code
+ GRAPH: con 1;
+ TEXT: con 2;
+ PEN: con 3;
+
+ # pen
+ CIRCLE: con 101;
+ CROSS: con 102;
+ SOLID: con 103;
+ DASHED: con 104;
+ INVIS: con 105;
+ REFERENCE: con 106;
+ DOTTED: con 107;
+
+ # text justify
+ LJUST: con 8r00;
+ CENTER: con 8r01;
+ RJUST: con 8r02;
+ HIGH: con 8r00;
+ MED: con 8r10;
+ BASE: con 8r20;
+ LOW: con 8r30;
+ UP: con 8r100;
+};
diff --git a/module/grid/announce.m b/module/grid/announce.m
new file mode 100644
index 00000000..a205c30c
--- /dev/null
+++ b/module/grid/announce.m
@@ -0,0 +1,5 @@
+Announce: module {
+ PATH: con "/dis/grid/lib/announce.dis";
+ init: fn();
+ announce: fn(): (string, ref Sys->Connection); # find a local address, any port, and return its name and an announced connection.
+};
diff --git a/module/grid/browse.m b/module/grid/browse.m
new file mode 100644
index 00000000..8c96817e
--- /dev/null
+++ b/module/grid/browse.m
@@ -0,0 +1,43 @@
+Browse: module
+{
+ PATH: con "/dis/grid/lib/browse.dis";
+
+ # panetype
+ SINGLEPANE: con 1; # does not work yet
+ SPLITPANE: con 2;
+ # filetype
+ DIRSONLY: con 3;
+ FILESONLY: con 4;
+ FILESORDIRS: con 5;
+ # selecttype
+ SINGLE: con 1;
+ MULTI: con 2;
+ SELECT: con 1;
+ TOGGLE: con 2;
+ NONE: con 3;
+ opened : list of string;
+ init : fn (top: ref Tk->Toplevel, rlabel, root: string, ptype, ftype, stype: int, pathrd : PathReader);
+ getselectedpath : fn (pane: int): string;
+ refresh : fn (top: ref Tk->Toplevel);
+ gotofile : fn (top: ref Tk->Toplevel, path:string, pnum: int);
+ opendir : fn (top: ref Tk->Toplevel, path, tkpath: string);
+ changepane : fn (top: ref Tk->Toplevel, ptype: int);
+ resizewin : fn (top: ref Tk->Toplevel, width, height: int);
+ selectfile : fn (top: ref Tk->Toplevel, pane, action: int, path, tkpath: string);
+ setscrollr : fn (top: ref Tk->Toplevel);
+ getpnum : fn (tkpath: string): int;
+ pane1see : fn (top: ref Tk->Toplevel);
+ gotopath : fn (top: ref Tk->Toplevel, dir: string, openfinal, pnum: int): string;
+ getpath : fn (top: ref Tk->Toplevel, f: string): string;
+ prevpath : fn (path: string): string;
+ setcentre : fn (top1, top2: ref Tk->Toplevel);
+ addselection : fn (top: ref Tk->Toplevel, file: string, val, args, dups: int, sval, sargs: string): string;
+ delselection : fn (top: ref Tk->Toplevel, n: string): string;
+ newfl : fn (top: ref Tk->Toplevel, rlabel, root: string);
+ setc3frame : fn (top: ref Tk->Toplevel, frame: string);
+ doargs : fn (top: ref Tk->Toplevel, lst: list of string);
+ getselected : fn (top: ref Tk->Toplevel, frame: string): list of (string, string, string);
+ movdiv : fn (top: ref Tk->Toplevel, x: int);
+ dialog : fn (ctxt: ref draw->Context, oldtop: ref Tk->Toplevel, butlist: list of string, title, msg: string): int;
+ getc3frame : fn (): string;
+}; \ No newline at end of file
diff --git a/module/grid/browser.m b/module/grid/browser.m
new file mode 100644
index 00000000..78dadebe
--- /dev/null
+++ b/module/grid/browser.m
@@ -0,0 +1,97 @@
+Browser: module {
+
+ PATH: con "/dis/grid/lib/browser.dis";
+
+ DESELECT: con 0;
+ SELECT: con 1;
+ TOGGLE: con 2;
+ OPEN: con 3;
+ CLOSE: con 4;
+
+ init: fn ();
+ dialog: fn (ctxt: ref draw->Context, oldtop: ref Tk->Toplevel, butlist: list of string, title, msg: string): int;
+ prevpath: fn (path: string): string;
+ setcentre: fn (top1, top2: ref Tk->Toplevel);
+
+ Browse: adt {
+ new: fn (top: ref Tk->Toplevel, tkchanname, root, rlabel: string, nopanes: int, reader: PathReader): ref Browse;
+ refresh: fn (b: self ref Browse);
+ defaultaction: fn (b: self ref Browse, lst: list of string, f: ref File);
+ getpath: fn (b: self ref Browse, tkpath: string): ref File;
+ opendir: fn (b: self ref Browse, file: File, tkpath: string, action: int): int;
+ newroot: fn (b: self ref Browse, root, rlabel: string);
+ changeview: fn (b: self ref Browse, nopanes: int);
+ selectfile: fn (b: self ref Browse, pane, action: int, file: File, tkpath: string);
+ gotoselectfile: fn (b: self ref Browse, file: File): string;
+ gotopath: fn (b: self ref Browse, dir: File, openfinal: int): (File, string);
+ getselected: fn (b: self ref Browse, pane: int): File;
+ addopened: fn (b: self ref Browse, file: File, add: int);
+ showpath: fn (b: self ref Browse, on: int);
+ resize: fn (b: self ref Browse);
+ top: ref Tk->Toplevel;
+ tkchan: string;
+ bgnorm, bgselect: string;
+ nopanes: int;
+ selected: array of Selected;
+ opened: list of File;
+ root, rlabel: string;
+ reader: PathReader;
+ pane1: File;
+ pane0width: string;
+ width: int;
+ showpathlabel: int;
+ released: int;
+ };
+
+ SELECTED: con 0;
+ UNSELECTED: con 1;
+ ALL: con 2;
+
+ Select: adt {
+ new: fn (top: ref Tk->Toplevel, tkchanname: string): ref Select;
+ addframe: fn (s: self ref Select, fname, title: string);
+ showframe: fn (s: self ref Select, fname: string);
+ delframe: fn (s: self ref Select, fname: string);
+ addselection: fn (s: self ref Select, fname, text: string, lp: list of ref Parameter, allowdups: int): string;
+ delselection: fn (s: self ref Select, fname, tkpath: string);
+ getselection: fn (s: self ref Select, fname: string): list of (string, list of ref Parameter);
+ getselected: fn (s: self ref Select, fname: string): string;
+ select: fn (s: self ref Select, fname, tkpath: string, action: int);
+ defaultaction: fn (s: self ref Select, lst: list of string);
+ resize: fn (s: self ref Select, width, height: int);
+ setscrollr: fn (s: self ref Select, fname: string);
+ top: ref Tk->Toplevel;
+ tkchan: string;
+ currfname, currfid: string;
+ frames: list of ref Frame;
+ };
+
+ Frame: adt {
+ name: string;
+ path: string;
+ selected: string;
+ };
+
+ Parameter: adt {
+ pick {
+ ArgIn =>
+ name, initval: string;
+ ArgOut =>
+ name, val: string;
+ IntIn =>
+ min, max, initval: int;
+ IntOut =>
+ val: int;
+ }
+ };
+
+ File: adt {
+ eq: fn (a,b: File): int;
+ path, qid: string;
+ };
+
+ Selected: adt {
+ file: File;
+ tkpath: string;
+ };
+}; \ No newline at end of file
diff --git a/module/grid/demo/block.m b/module/grid/demo/block.m
new file mode 100644
index 00000000..a20ab87a
--- /dev/null
+++ b/module/grid/demo/block.m
@@ -0,0 +1,14 @@
+Block : module
+{
+ PATH: con "/dis/grid/demo/block.dis";
+
+ init : fn (pathname: string, ep: Exproc);
+ slave : fn ();
+ writedata : fn (s: string);
+ masterinit : fn (noblocks: int);
+ reader : fn (noblocks: int, chanout: chan of string, sync: chan of int);
+ makefile : fn (block: int, let: string): string;
+ err : fn (s: string);
+ cleanfiles : fn (delpath: string);
+ isin : fn (l: list of string, s: string): int;
+}; \ No newline at end of file
diff --git a/module/grid/demo/exproc.m b/module/grid/demo/exproc.m
new file mode 100644
index 00000000..f4b7ec04
--- /dev/null
+++ b/module/grid/demo/exproc.m
@@ -0,0 +1,7 @@
+Exproc : module
+{
+ getslavedata : fn (lst: list of string);
+ doblock : fn (block: int, bpath: string);
+ readblock : fn (block: int, dir: string, chanout: chan of string): int;
+ finish : fn (waittime: int, tkchan: chan of string);
+}; \ No newline at end of file
diff --git a/module/grid/fbrowse.m b/module/grid/fbrowse.m
new file mode 100644
index 00000000..61107d20
--- /dev/null
+++ b/module/grid/fbrowse.m
@@ -0,0 +1,13 @@
+FBrowse : module
+{
+ PATH: con "/dis/grid/lib/fbrowse.dis";
+ NOTHING: con 0;
+ RUN: con 1;
+ OPEN: con 2;
+ WRITE: con 3;
+ ERROR: con -1;
+
+ init : fn (ctxt : ref Draw->Context, title, root, currdir: string): string;
+ readpath : fn (dir: Browser->File): (array of ref sys->Dir, int);
+};
+
diff --git a/module/grid/pathreader.m b/module/grid/pathreader.m
new file mode 100644
index 00000000..7ec4f0f4
--- /dev/null
+++ b/module/grid/pathreader.m
@@ -0,0 +1,3 @@
+PathReader : module {
+ readpath: fn (dir: Browser->File): (array of ref sys->Dir, int);
+}; \ No newline at end of file
diff --git a/module/grid/readjpg.m b/module/grid/readjpg.m
new file mode 100644
index 00000000..4576381c
--- /dev/null
+++ b/module/grid/readjpg.m
@@ -0,0 +1,95 @@
+Readjpg: module
+{
+
+ PATH: con "/dis/grid/readjpg.dis";
+
+ ImageSource: adt
+ {
+ width: int;
+ height: int;
+ origw: int;
+ origh: int;
+ i: int;
+ jstate: ref Jpegstate;
+ data: array of byte;
+ };
+
+ Jpegstate: adt
+ {
+ # variables in i/o routines
+ sr: int; # shift register, right aligned
+ cnt: int; # # bits in right part of sr
+
+ Nf: int;
+ comp: array of Framecomp;
+ mode: byte;
+ X,Y: int;
+ qt: array of array of int; # quantization tables
+ dcht: array of ref Huffman;
+ acht: array of ref Huffman;
+ Ns: int;
+ scomp: array of Scancomp;
+ Ss: int;
+ Se: int;
+ Ah: int;
+ Al: int;
+ ri: int;
+ nseg: int;
+ nblock: array of int;
+
+ # progressive scan
+ dccoeff: array of array of int;
+ accoeff: array of array of array of int; # only need 8 bits plus quantization
+ nacross: int;
+ ndown: int;
+ Hmax: int;
+ Vmax: int;
+ };
+
+ Huffman: adt
+ {
+ bits: array of int;
+ size: array of int;
+ code: array of int;
+ val: array of int;
+ mincode: array of int;
+ maxcode: array of int;
+ valptr: array of int;
+ # fast lookup
+ value: array of int;
+ shift: array of int;
+ };
+
+ Framecomp: adt # Frame component specifier from SOF marker
+ {
+ C: int;
+ H: int;
+ V: int;
+ Tq: int;
+ };
+
+ Scancomp: adt # Frame component specifier from SOF marker
+ {
+ C: int;
+ tdc: int;
+ tac: int;
+ };
+
+ # Constants, all preceded by byte 16rFF
+ SOF: con 16rC0; # Start of Frame
+ SOF2: con 16rC2; # Start of Frame; progressive Huffman
+ DHT: con 16rC4; # Define Huffman Tables
+ RST: con 16rD0; # Restart interval termination
+ SOI: con 16rD8; # Start of Image
+ EOI: con 16rD9; # End of Image
+ SOS: con 16rDA; # Start of Scan
+ DQT: con 16rDB; # Define quantization tables
+ DNL: con 16rDC; # Define number of lines
+ DRI: con 16rDD; # Define restart interval
+ APPn: con 16rE0; # Reserved for application segments
+ COM: con 16rFE; # Comment
+
+ init : fn (disp: ref Draw->Display);
+ fjpg2img : fn (fd: ref sys->FD, cachepath: string, chanin, chanout: chan of string): ref Image;
+ jpg2img : fn (filename, cachepath: string, chanin, chanout: chan of string): ref Image;
+}; \ No newline at end of file
diff --git a/module/grid/regpoll.m b/module/grid/regpoll.m
new file mode 100644
index 00000000..22ef09d2
--- /dev/null
+++ b/module/grid/regpoll.m
@@ -0,0 +1,6 @@
+RegPoll : module {
+ PATH: con "/usr/danny/res/regpoll.dis";
+
+ STOPPED, STARTED, ERROR: con iota;
+ init : fn (regaddr: string): (chan of int, chan of int);
+};
diff --git a/module/grid/srvbrowse.m b/module/grid/srvbrowse.m
new file mode 100644
index 00000000..a1da02f3
--- /dev/null
+++ b/module/grid/srvbrowse.m
@@ -0,0 +1,16 @@
+Srvbrowse: module
+{
+ PATH: con "/dis/grid/lib/srvbrowse.dis";
+
+ services : list of ref Registries->Service;
+
+ init : fn ();
+ refreshservices : fn (filter: list of list of (string, string));
+ servicepath2Service : fn (path, qid: string): list of ref Registries->Service;
+ servicepath2Dir : fn (path: string, qid: int): (array of ref sys->Dir, int);
+ getresname : fn (srvc: ref Registries->Service): (string, string);
+ getqid : fn (srvc: ref Registries->Service): string;
+ find : fn (filter: list of list of (string, string)): list of ref Registries->Service;
+ addservice: fn (srvc: ref Registries->Service);
+ searchwin: fn (ctxt: ref Draw->Context, chanout: chan of string, filter: list of list of (string, string));
+}; \ No newline at end of file
diff --git a/module/hash.m b/module/hash.m
new file mode 100644
index 00000000..270dd9cd
--- /dev/null
+++ b/module/hash.m
@@ -0,0 +1,23 @@
+Hash: module{
+ PATH: con "/dis/lib/hash.dis";
+ fun1, fun2: fn(s:string,n:int):int;
+
+ HashVal: adt{
+ i: int;
+ r: real;
+ s: string;
+ };
+ HashNode: adt{
+ key:string;
+ val:ref HashVal; # insert() can update contents
+ };
+ HashTable: adt{
+ a: array of list of HashNode;
+ find: fn(h:self ref HashTable, key:string):ref HashVal;
+ insert: fn(h:self ref HashTable, key:string, val:HashVal);
+ delete: fn(h:self ref HashTable, key:string);
+ all: fn(h:self ref HashTable): list of HashNode;
+ };
+ new: fn(size:int):ref HashTable;
+};
+
diff --git a/module/html.m b/module/html.m
new file mode 100644
index 00000000..170cd8bd
--- /dev/null
+++ b/module/html.m
@@ -0,0 +1,41 @@
+HTML: module
+{
+ PATH: con "/dis/lib/html.dis";
+
+ Lex: adt
+ {
+ tag: int;
+ text: string; # text in Data, attribute text in tag
+ attr: list of Attr;
+ };
+
+ Attr: adt
+ {
+ name: string;
+ value: string;
+ };
+
+ # sorted in lexical order; used as array indices
+ Notfound,
+ Ta, Taddress, Tapplet, Tarea, Tatt_footer, Tb,
+ Tbase, Tbasefont, Tbig, Tblink, Tblockquote, Tbody,
+ Tbq, Tbr, Tcaption, Tcenter, Tcite, Tcode, Tcol, Tcolgroup,
+ Tdd, Tdfn, Tdir, Tdiv, Tdl, Tdt, Tem,
+ Tfont, Tform, Tframe, Tframeset,
+ Th1, Th2, Th3, Th4, Th5, Th6, Thead, Thr, Thtml, Ti, Timg,
+ Tinput, Tisindex, Titem, Tkbd, Tli, Tlink, Tmap, Tmenu,
+ Tmeta, Tnobr, Tnoframes, Tol, Toption, Tp, Tparam, Tpre,
+ Tq, Tsamp, Tscript, Tselect, Tsmall, Tstrike, Tstrong,
+ Tstyle, Tsub, Tsup, Tt, Ttable, Ttbody, Ttd, Ttextarea, Ttextflow, Ttfoot, Tth,
+ Tthead, Ttitle, Ttr, Ttt, Tu, Tul, Tvar
+ : con iota;
+ RBRA: con 1000;
+ Data: con 2000;
+ Latin1, UTF8: con iota; # charsets
+
+ lex: fn(b: array of byte, charset: int, keepnls: int): array of ref Lex;
+ attrvalue: fn(attr: list of Attr, name: string): (int, string);
+ globalattr: fn(html: array of ref Lex, tag: int, attr: string): (int, string);
+ isbreak: fn(h: array of ref Lex, i: int): int;
+ lex2string: fn(l: ref Lex): string;
+};
diff --git a/module/imagefile.m b/module/imagefile.m
new file mode 100644
index 00000000..2e386aa7
--- /dev/null
+++ b/module/imagefile.m
@@ -0,0 +1,48 @@
+RImagefile: module
+{
+ READGIFPATH: con "/dis/lib/readgif.dis";
+ READJPGPATH: con "/dis/lib/readjpg.dis";
+ READXBMPATH: con "/dis/lib/readxbitmap.dis";
+ READPICPATH: con "/dis/lib/readpicfile.dis";
+ READPNGPATH: con "/dis/lib/readpng.dis";
+
+ Rawimage: adt
+ {
+ r: Draw->Rect;
+ cmap: array of byte;
+ transp: int; # transparency flag (only for nchans=1)
+ trindex: byte; # transparency index
+ nchans: int;
+ chans: array of array of byte;
+ chandesc:int;
+
+ fields: int; # defined by format
+ };
+
+ # chandesc
+ CRGB: con 0; # three channels, no map
+ CY: con 1; # one channel, luminance
+ CRGB1: con 2; # one channel, map present
+
+ init: fn(bufio: Bufio);
+ read: fn(fd: ref Bufio->Iobuf): (ref Rawimage, string);
+ readmulti: fn(fd: ref Bufio->Iobuf): (array of ref Rawimage, string);
+};
+
+WImagefile: module
+{
+ WRITEGIFPATH: con "/dis/lib/writegif.dis";
+
+ init: fn(bufio: Bufio);
+# write: fn(fd: ref Bufio->Iobuf, ref RImagefile->Rawimage): string;
+ writeimage: fn(fd: ref Bufio->Iobuf, image: ref Draw->Image): string;
+};
+
+
+Imageremap: module
+{
+ PATH: con "/dis/lib/imageremap.dis";
+
+ init: fn(d: ref Draw->Display);
+ remap: fn(i: ref RImagefile->Rawimage, d: ref Draw->Display, errdiff: int): (ref Draw->Image, string);
+};
diff --git a/module/inflate.m b/module/inflate.m
new file mode 100644
index 00000000..c547ec16
--- /dev/null
+++ b/module/inflate.m
@@ -0,0 +1,25 @@
+Inflate: module
+{
+ PATH: con "/dis/lib/inflate.dis";
+
+ InflateBlock: con 16r8000;
+ InflateMask: con 16rf0000;
+
+ InflateEmptyIn,
+ InflateFlushOut,
+ InflateAck,
+ InflateDone,
+ InflateError: con iota + (1 << 16) + 1;
+
+ # conduit for data streaming between inflate and its producer/consumer
+ InflateIO: adt
+ {
+ ibuf: array of byte; # input buffer [InflateBlock]
+ obuf: array of byte; # output buffer [InflateBlock]
+ c: chan of int; # for inflate <-> server comm.
+ };
+
+ init: fn();
+ reset: fn(): ref InflateIO;
+ inflate: fn();
+};
diff --git a/module/ip.m b/module/ip.m
new file mode 100644
index 00000000..d25278d1
--- /dev/null
+++ b/module/ip.m
@@ -0,0 +1,104 @@
+IP: module
+{
+ PATH: con "/dis/lib/ip.dis";
+
+ IPaddrlen: con 16;
+ IPv4addrlen: con 4;
+ IPv4off: con 12;
+
+ IPaddr: adt {
+ a: array of byte;
+
+ newv6: fn(nil: array of byte): IPaddr;
+ newv4: fn(nil: array of byte): IPaddr;
+ copy: fn(nil: self IPaddr): IPaddr;
+ eq: fn(nil: self IPaddr, v: IPaddr): int;
+ mask: fn(nil: self IPaddr, m: IPaddr): IPaddr;
+ maskn: fn(nil: self IPaddr, m: IPaddr): IPaddr;
+ isv4: fn(nil: self IPaddr): int;
+ ismulticast: fn(nil: self IPaddr): int;
+ isvalid: fn(nil: self IPaddr): int;
+
+ v4: fn(nil: self IPaddr): array of byte;
+ v6: fn(nil: self IPaddr): array of byte;
+ class: fn(nil: self IPaddr): int;
+ classmask: fn(nil: self IPaddr): IPaddr;
+
+ parse: fn(s: string): (int, IPaddr);
+ parsemask: fn(s: string): (int, IPaddr);
+ parsecidr: fn(s: string): (int, IPaddr, IPaddr);
+
+ text: fn(nil: self IPaddr): string;
+ masktext: fn(nil: self IPaddr): string;
+ };
+
+ v4bcast, v4allsys, v4allrouter, v4noaddr, noaddr, allbits, selfv6, selfv4: IPaddr;
+ v4prefix: array of byte;
+
+ Ifcaddr: adt {
+ ip: IPaddr;
+ mask: IPaddr;
+ net: IPaddr;
+ preflt: big;
+ validlt: big;
+ };
+
+ Ipifc: adt {
+ index: int; # /net/ipifc/N
+ dev: string; # bound device
+ addrs: list of ref Ifcaddr;
+ sendra: int; # !=0, send router adverts
+ recvra: int; # !=0, receive router adverts
+ mtu: int;
+ pktin: big; # packets in
+ pktout: big; # packets out
+ errin: big; # input errors
+ errout: big; # output errors
+ rp: IPv6rp; # IPv6 route advert params
+ };
+
+ IPv6rp: adt {
+ mflag: int;
+ oflag: int;
+ maxraint: int; # max route advert interval
+ minraint: int; # min route advert interval
+ linkmtu: int;
+ reachtime: int;
+ rxmitra: int;
+ ttl: int;
+ routerlt: int;
+ };
+
+ Udp4hdrlen: con 2*IPv4addrlen+2*2;
+ OUdphdrlen: con 2*IPaddrlen+2*2;
+
+ Udphdrlen: con 52;
+ Udpraddr: con 0;
+ Udpladdr: con Udpraddr + IPaddrlen;
+ Udpifcaddr: con Udpladdr + IPaddrlen;
+ Udprport: con Udpifcaddr + IPaddrlen;
+ Udplport: con Udprport + 2;
+
+ Udphdr: adt {
+ raddr: IPaddr;
+ laddr: IPaddr;
+ ifcaddr: IPaddr;
+ rport: int;
+ lport: int;
+
+ new: fn(): ref Udphdr;
+ unpack: fn(a: array of byte, n: int): ref Udphdr;
+ pack: fn(h: self ref Udphdr, a: array of byte, n: int);
+ };
+
+ init: fn();
+ readipifc: fn(net: string, index: int): (list of ref Ipifc, string);
+ addressesof: fn(l: list of ref Ipifc, all: int): list of IPaddr;
+ interfaceof: fn(l: list of ref Ipifc, ip: IPaddr): (ref Ipifc, ref Ifcaddr);
+ ownerof: fn(l: list of ref Ipifc, ip: IPaddr): (ref Ipifc, ref Ifcaddr);
+
+ get2: fn(a: array of byte, o: int): int;
+ put2: fn(a: array of byte, o: int, v: int): int;
+ get4: fn(a: array of byte, o: int): int;
+ put4: fn(a: array of byte, o: int, v: int): int;
+};
diff --git a/module/ipattr.m b/module/ipattr.m
new file mode 100644
index 00000000..bad57f69
--- /dev/null
+++ b/module/ipattr.m
@@ -0,0 +1,20 @@
+IPattr: module
+{
+
+ PATH: con "/dis/lib/ipattr.dis";
+
+ Netattr: adt {
+ name: string;
+ pairs: list of ref Attrdb->Attr;
+ net: IP->IPaddr;
+ mask: IP->IPaddr;
+ };
+
+ init: fn(attrdb: Attrdb, ip: IP);
+
+ dbattr: fn(s: string): string;
+ findnetattr: fn(db: ref Attrdb->Db, attr: string, val: string, rattr: string): (string, string);
+ findnetattrs: fn(db: ref Attrdb->Db, attr: string, val: string, rattrs: list of string): (list of (IP->IPaddr, list of ref Netattr), string);
+ valueof: fn(l: list of ref Netattr, attr: string): list of string;
+ netvalueof: fn(l: list of ref Netattr, attr: string, ip: IP->IPaddr): list of string;
+};
diff --git a/module/ir.m b/module/ir.m
new file mode 100644
index 00000000..a7bab18e
--- /dev/null
+++ b/module/ir.m
@@ -0,0 +1,43 @@
+Ir: module
+{
+ PATH: con "/dis/lib/ir.dis";
+ SIMPATH: con "/dis/lib/irsim.dis";
+ MPATH: con "/dis/lib/irmpath.dis";
+ SAGEPATH: con "/dis/lib/irsage.dis";
+
+ #
+ # "standard" remote buttons
+ #
+ Zero: con 0;
+ One: con 1;
+ Two: con 2;
+ Three: con 3;
+ Four: con 4;
+ Five: con 5;
+ Six: con 6;
+ Seven: con 7;
+ Eight: con 8;
+ Nine: con 9;
+ ChanUP: con 10;
+ ChanDN: con 11;
+ VolUP: con 12;
+ VolDN: con 13;
+ FF: con 14;
+ Rew: con 15;
+ Up: con 16;
+ Dn: con 17;
+ Select: con 18;
+ Power: con 19;
+ Enter: con 20;
+ Rcl: con 21;
+ Record: con 22;
+ Mute: con 23;
+ #
+ # Control
+ #
+ Error: con 9999;
+ EOF: con -1;
+
+ init: fn(c, p: chan of int): int;
+ translate: fn(c: int): int;
+};
diff --git a/module/itslib.m b/module/itslib.m
new file mode 100644
index 00000000..c1046114
--- /dev/null
+++ b/module/itslib.m
@@ -0,0 +1,24 @@
+
+Itslib: module {
+
+ PATH: con "/dis/lib/itslib.dis";
+
+ init: fn(): ref Tconfig;
+ S_INFO: con 0;
+ S_WARN: con 1;
+ S_ERROR: con 2;
+ S_FATAL: con 3;
+ S_STIME: con 4;
+ S_ETIME: con 5;
+ ENV_VERBOSITY: con "ITS_VERBOSITY";
+ ENV_MFD: con "ITS_MFD";
+
+
+ Tconfig: adt {
+ verbosity: int;
+ mfd: ref Sys->FD;
+ report: fn(t: self ref Tconfig, sev: int, verb: int, msg: string);
+ done: fn(t: self ref Tconfig);
+ };
+
+};
diff --git a/module/keyboard.m b/module/keyboard.m
new file mode 100644
index 00000000..95a6d666
--- /dev/null
+++ b/module/keyboard.m
@@ -0,0 +1,50 @@
+Keyboard : module {
+ # Inferno Generic Scan Conversions
+ # this file needs to be kept in sync with include/keyboard.h
+
+ No: con -1;
+ Esc: con 16r1b;
+
+ Spec: con 16rE000; # Special Function Keys - mapped to Unicode reserved range
+ Shift: con Spec|16r00; # Shifter (Held) Keys
+ View: con Spec|16r10; # View Keys
+ PF: con Spec|16r20; # num pad
+ KF: con Spec|16r40; # function keys
+
+ LShift: con Shift|0;
+ RShift: con Shift|1;
+ LCtrl: con Shift|2;
+ RCtrl: con Shift|3;
+ Caps: con Shift|4;
+ Num: con Shift|5;
+ Meta: con Shift|6;
+ LAlt: con Shift|7;
+ RAlt: con Shift|8;
+ NShifts: con 9; # total number of shift keys
+
+ Home: con View|0;
+ End: con View|1;
+ Up: con View|2;
+ Down: con View|3;
+ Left: con View|4;
+ Right: con View|5;
+ Pgup: con View|6;
+ Pgdown: con View|7;
+ BackTab: con View|8;
+
+ Scroll: con Spec|16r62;
+ Ins: con Spec|16r63;
+ Del: con Spec|16r64;
+ Print: con Spec|16r65;
+ Pause: con Spec|16r66;
+ Middle: con Spec|16r67;
+ Break: con Spec|16r66;
+ SysRq: con Spec|16r69;
+ PwrOn: con Spec|16r6c;
+ PwrOff: con Spec|16r6d;
+ PwrLow: con Spec|16r6e;
+ Latin: con Spec|16r6f;
+
+ APP: con Spec|16r200; # for application use (ALT keys)
+};
+
diff --git a/module/keyring.m b/module/keyring.m
new file mode 100644
index 00000000..753aea12
--- /dev/null
+++ b/module/keyring.m
@@ -0,0 +1,238 @@
+#
+# security routines implemented in C
+#
+Keyring: module
+{
+ PATH: con "$Keyring";
+
+ # infinite precision integers
+ IPint: adt
+ {
+ x: int; # dummy for C compiler for runt.h
+
+ # conversions
+ iptob64: fn(i: self ref IPint): string;
+ b64toip: fn(str: string): ref IPint;
+ iptobytes: fn(i: self ref IPint): array of byte;
+ iptobebytes: fn(i: self ref IPint): array of byte;
+ bytestoip: fn(buf: array of byte): ref IPint;
+ bebytestoip: fn(mag: array of byte): ref IPint;
+ inttoip: fn(i: int): ref IPint;
+ iptoint: fn(i: self ref IPint): int;
+ iptostr: fn(i: self ref IPint, base: int): string;
+ strtoip: fn(str: string, base: int): ref IPint;
+
+ # create a random large integer using the accelerated generator
+ random: fn(minbits, maxbits: int): ref IPint;
+
+ # operations
+ bits: fn(i: self ref IPint): int;
+ expmod: fn(base: self ref IPint, exp, mod: ref IPint): ref IPint;
+ invert: fn(base: self ref IPint, mod: ref IPint): ref IPint;
+ add: fn(i1: self ref IPint, i2: ref IPint): ref IPint;
+ sub: fn(i1: self ref IPint, i2: ref IPint): ref IPint;
+ neg: fn(i: self ref IPint): ref IPint;
+ mul: fn(i1: self ref IPint, i2: ref IPint): ref IPint;
+ div: fn(i1: self ref IPint, i2: ref IPint): (ref IPint, ref IPint);
+ eq: fn(i1: self ref IPint, i2: ref IPint): int;
+ cmp: fn(i1: self ref IPint, i2: ref IPint): int;
+ copy: fn(i: self ref IPint): ref IPint;
+
+ # shifts
+ shl: fn(i: self ref IPint, n: int): ref IPint;
+ shr: fn(i: self ref IPint, n: int): ref IPint;
+ };
+
+ # signature algorithm
+ SigAlg: adt
+ {
+ name: string;
+ # C function pointers are hidden
+ };
+
+ # generic public key
+ PK: adt
+ {
+ sa: ref SigAlg; # signature algorithm
+ owner: string; # owner's name
+ # key and system parameters are hidden
+ };
+
+ # generic secret key
+ SK: adt
+ {
+ sa: ref SigAlg; # signature algorithm
+ owner: string; # owner's name
+ # key and system parameters are hidden
+ };
+
+ # generic certificate
+ Certificate: adt
+ {
+ sa: ref SigAlg; # signature algorithm
+ ha: string; # hash algorithm
+ signer: string; # name of signer
+ exp: int; # expiration date
+ # actual signature is hidden
+ };
+
+ # state held while creating digests
+ DigestState: adt
+ {
+ x: int; # dummy for C compiler for runt.h
+ # all the state is hidden
+
+ copy: fn(d: self ref DigestState): ref DigestState;
+ };
+
+ # expanded AES key + state for chaining
+ AESstate: adt
+ {
+ x: int; # dummy for C compiler for runt.h
+ # all the state is hidden
+ };
+
+ # expanded DES key + state for chaining
+ DESstate: adt
+ {
+ x: int; # dummy for C compiler for runt.h
+ # all the state is hidden
+ };
+
+ # expanded IDEA key + state for chaining
+ IDEAstate: adt
+ {
+ x: int; # dummy for C compiler for runt.h
+ # all the state is hidden
+ };
+
+ # expanded RC4 key + encryption state
+ RC4state: adt
+ {
+ x: int; # dummy for C compiler for runt.h
+ # all the state is hidden
+ };
+
+ # authentication info
+ Authinfo: adt
+ {
+ mysk: ref SK; # my private key
+ mypk: ref PK; # my public key
+ cert: ref Certificate; # signature of my public key
+ spk: ref PK; # signers public key
+ alpha: ref IPint; # diffie helman parameters
+ p: ref IPint;
+ };
+
+ # convert types to byte strings
+ certtostr: fn (c: ref Certificate): string;
+ pktostr: fn (pk: ref PK): string;
+ sktostr: fn (sk: ref SK): string;
+
+ # parse byte strings into types
+ strtocert: fn (s: string): ref Certificate;
+ strtopk: fn (s: string): ref PK;
+ strtosk: fn (s: string): ref SK;
+
+ # convert types to attr/value pairs
+ certtoattr: fn (c: ref Certificate): string;
+ pktoattr: fn (pk: ref PK): string;
+ sktoattr: fn (sk: ref SK): string;
+
+ # parse a/v pairs into types
+# attrtocert: fn (s: string): ref Certificate;
+# attrtopk: fn (s: string): ref PK;
+# attrtosk: fn (s: string): ref SK;
+
+ # create and verify signatures
+ sign: fn (sk: ref SK, exp: int, state: ref DigestState, ha: string):
+ ref Certificate;
+ verify: fn (pk: ref PK, cert: ref Certificate, state: ref DigestState):
+ int;
+ signm: fn (sk: ref SK, m: ref IPint, ha: string):
+ ref Certificate;
+ verifym: fn (pk: ref PK, cert: ref Certificate, m: ref IPint):
+ int;
+
+ # generate keys
+ genSK: fn (algname, owner: string, length: int): ref SK;
+ genSKfromPK: fn (pk: ref PK, owner: string): ref SK;
+ sktopk: fn (sk: ref SK): ref PK;
+
+ # digests
+ sha1: fn(buf: array of byte, n: int, digest: array of byte, state: ref DigestState):
+ ref DigestState;
+ md4: fn(buf: array of byte, n: int, digest: array of byte, state: ref DigestState):
+ ref DigestState;
+ md5: fn(buf: array of byte, n: int, digest: array of byte, state: ref DigestState):
+ ref DigestState;
+
+ hmac_sha1: fn(data: array of byte, n: int, key: array of byte, digest: array of byte, state: ref DigestState):
+ ref DigestState;
+ hmac_md5: fn(data: array of byte, n: int, key: array of byte, digest: array of byte, state: ref DigestState):
+ ref DigestState;
+
+ # encryption interfaces
+ Encrypt: con 0;
+ Decrypt: con 1;
+
+ AESbsize: con 16;
+
+ aessetup: fn(key: array of byte, ivec: array of byte): ref AESstate;
+ aescbc: fn(state: ref AESstate, buf: array of byte, n: int, direction: int);
+
+ DESbsize: con 8;
+
+ dessetup: fn(key: array of byte, ivec: array of byte): ref DESstate;
+ desecb: fn(state: ref DESstate, buf: array of byte, n: int, direction: int);
+ descbc: fn(state: ref DESstate, buf: array of byte, n: int, direction: int);
+
+ IDEAbsize: con 8;
+
+ ideasetup: fn(key: array of byte, ivec: array of byte): ref IDEAstate;
+ ideaecb: fn(state: ref IDEAstate, buf: array of byte, n: int, direction: int);
+ ideacbc: fn(state: ref IDEAstate, buf: array of byte, n: int, direction: int);
+
+ rc4setup: fn(seed: array of byte): ref RC4state;
+ rc4: fn(state: ref RC4state, buf: array of byte, n: int);
+ rc4skip: fn(state: ref RC4state, n: int);
+ rc4back: fn(state: ref RC4state, n: int);
+
+ # create an alpha and p for diffie helman exchanges
+ dhparams: fn(nbits: int): (ref IPint, ref IPint);
+
+ # comm link authentication is symmetric
+ auth: fn(fd: ref Sys->FD, info: ref Authinfo, setid: int): (string, array of byte);
+
+ # auth io
+ readauthinfo: fn(filename: string): ref Authinfo;
+ writeauthinfo: fn(filename: string, info: ref Authinfo): int;
+
+ # message io on a delimited connection (ssl for example)
+ # messages > 4096 bytes are truncated
+ # errors > 64 bytes are truncated
+ # getstring and getbytearray return (result, error).
+ getstring: fn(fd: ref Sys->FD): (string, string);
+ putstring: fn(fd: ref Sys->FD, s: string): int;
+ getbytearray: fn(fd: ref Sys->FD): (array of byte, string);
+ putbytearray: fn(fd: ref Sys->FD, a: array of byte, n: int): int;
+ puterror: fn(fd: ref Sys->FD, s: string): int;
+
+ # to send and receive messages when ssl isn't pushed
+ getmsg: fn(fd: ref Sys->FD): array of byte;
+ sendmsg: fn(fd: ref Sys->FD, buf: array of byte, n: int): int;
+ senderrmsg: fn(fd: ref Sys->FD, s: string): int;
+
+ # algorithms
+ DEScbc: con 0;
+ DESecb: con 1;
+ SHA1: con 2;
+ MD5: con 3;
+ MD4: con 4;
+ IDEAcbc: con 5;
+ IDEAecb: con 6;
+
+ SHA1dlen: con 20;
+ MD5dlen: con 16;
+ MD4dlen: con 16;
+};
diff --git a/module/keyset.m b/module/keyset.m
new file mode 100644
index 00000000..f807fda3
--- /dev/null
+++ b/module/keyset.m
@@ -0,0 +1,8 @@
+Keyset: module
+{
+ PATH: con "/dis/lib/keyset.dis";
+
+ init: fn(): string;
+ pkhash: fn(pk: string): string;
+ keysforsigner: fn(signername: string, spk: string, user: string, dir: string): (list of (string, string, string), string);
+};
diff --git a/module/libc.m b/module/libc.m
new file mode 100644
index 00000000..f3bfda3c
--- /dev/null
+++ b/module/libc.m
@@ -0,0 +1,30 @@
+Libc: module
+{
+ PATH: con "/dis/lib/libc.dis";
+
+ isalnum: fn(c: int): int;
+ isalpha: fn(c: int): int;
+ isascii: fn(c: int): int;
+ iscntrl: fn(c: int): int;
+ isdigit: fn(c: int): int;
+ isgraph: fn(c: int): int;
+ islower: fn(c: int): int;
+ isprint: fn(c: int): int;
+ ispunct: fn(c: int): int;
+ isspace: fn(c: int): int;
+ isupper: fn(c: int): int;
+ isxdigit: fn(c: int): int;
+
+ tolower: fn(c: int): int;
+ toupper: fn(c: int): int;
+ toascii: fn(c: int): int;
+
+ strchr: fn(s: string, n: int): int;
+ strrchr: fn(s: string, n: int): int;
+ strncmp: fn(s1: string, s2: string, n: int): int;
+
+ abs: fn(n: int): int;
+ min: fn(m: int, n: int): int;
+ max: fn(m: int, n: int): int;
+
+};
diff --git a/module/libc0.m b/module/libc0.m
new file mode 100644
index 00000000..1c3257cf
--- /dev/null
+++ b/module/libc0.m
@@ -0,0 +1,40 @@
+Libc0: module
+{
+ PATH: con "/dis/lib/libc0.dis";
+
+ isalnum: fn(c: int): int;
+ isalpha: fn(c: int): int;
+ isascii: fn(c: int): int;
+ iscntrl: fn(c: int): int;
+ isdigit: fn(c: int): int;
+ isgraph: fn(c: int): int;
+ islower: fn(c: int): int;
+ isprint: fn(c: int): int;
+ ispunct: fn(c: int): int;
+ isspace: fn(c: int): int;
+ isupper: fn(c: int): int;
+ isxdigit: fn(c: int): int;
+
+ tolower: fn(c: int): int;
+ toupper: fn(c: int): int;
+ toascii: fn(c: int): int;
+
+ strlen: fn(s: array of byte): int;
+ strcmp: fn(s1: array of byte, s2: array of byte): int;
+ strcpy: fn(s1: array of byte, s2: array of byte): array of byte;
+ strcat: fn(s1: array of byte, s2: array of byte): array of byte;
+ strncmp: fn(s1: array of byte, s2: array of byte, n: int): int;
+ strncpy: fn(s1: array of byte, s2: array of byte, n: int): array of byte;
+ strncat: fn(s1: array of byte, s2: array of byte, n: int): array of byte;
+ strdup: fn(s: array of byte): array of byte;
+ strchr: fn(s: array of byte, n: int): array of byte;
+ strrchr: fn(s: array of byte, n: int): array of byte;
+
+ abs: fn(n: int): int;
+ min: fn(m: int, n: int): int;
+ max: fn(m: int, n: int): int;
+
+ ls2aab: fn(argl: list of string): array of array of byte;
+ s2ab: fn(s: string): array of byte;
+ ab2s: fn(a: array of byte): string;
+};
diff --git a/module/linalg.m b/module/linalg.m
new file mode 100644
index 00000000..ccc3288d
--- /dev/null
+++ b/module/linalg.m
@@ -0,0 +1,24 @@
+# The convention used here for storing matrices is the same commonly
+# used for scientific programming in C, namely linearizing in Fortran order.
+# Let A be an m by n matrix. We represent this by
+# a: array of real;
+# m, n, lda: int;
+# where the variable lda ("leading dimension of a") is used so that a
+# succession of matrix problems of varying sizes can be created without
+# wholesale copying of data. The element of A in the i-th row and j-th column
+# is stored in a[i+lda*j], where 0<=i<m and 0<=j<n. This 0-origin indexing
+# is used everywhere, and in particular in permutation vectors.
+
+LinAlg: module{
+ PATH: con "/dis/math/linalg.dis";
+
+ Vector: type array of real;
+ Matrix: adt{
+ m, L, n: int; # rows, column stride, columns
+ a: Vector; # data, stored A[i,j] = a[i+L*j]
+ };
+
+ dgefa: fn(a:array of real, lda, n:int, ipvt:array of int): int;
+ dgesl: fn(a:array of real, lda, n:int, ipvt:array of int, b:array of real, job:int);
+ printmat: fn(label:string, a:array of real, lda, m, n:int);
+};
diff --git a/module/loader.m b/module/loader.m
new file mode 100644
index 00000000..597e2bab
--- /dev/null
+++ b/module/loader.m
@@ -0,0 +1,48 @@
+#
+# External loader interface
+#
+Nilmod: module
+{
+};
+
+Loader: module
+{
+ PATH: con "$Loader";
+
+ Inst: adt
+ {
+ op: byte;
+ addr: byte;
+ src: int;
+ mid: int;
+ dst: int;
+ };
+
+ Typedesc: adt
+ {
+ size: int;
+ map: array of byte;
+ };
+
+ Link: adt
+ {
+ name: string;
+ sig: int;
+ pc: int;
+ tdesc: int;
+ };
+
+ Niladt: adt
+ {
+ };
+
+ ifetch: fn(mp: Nilmod): array of Inst;
+ tdesc: fn(mp: Nilmod): array of Typedesc;
+ newmod: fn(name: string, ss, nlink: int,
+ inst: array of Inst, data: ref Niladt): Nilmod;
+ tnew: fn(mp: Nilmod, size: int, map: array of byte): int;
+ link: fn(mp: Nilmod): array of Link;
+ ext: fn(mp: Nilmod, idx, pc: int, tdesc: int): int;
+ dnew: fn(size: int, map: array of byte): ref Niladt;
+ compile: fn(mp: Nilmod, flag: int): int;
+};
diff --git a/module/lock.m b/module/lock.m
new file mode 100644
index 00000000..ffd818c5
--- /dev/null
+++ b/module/lock.m
@@ -0,0 +1,13 @@
+Lock: module
+{
+ PATH: con "/dis/lib/lock.dis";
+
+ Semaphore: adt {
+ c: chan of int;
+ obtain: fn(nil: self ref Semaphore);
+ release: fn(nil: self ref Semaphore);
+ new: fn(): ref Semaphore;
+ };
+
+ init: fn();
+};
diff --git a/module/man.m b/module/man.m
new file mode 100644
index 00000000..3da6ad73
--- /dev/null
+++ b/module/man.m
@@ -0,0 +1,41 @@
+Parseman: module {
+ PATH: con "/dis/lib/parseman.dis";
+
+ Metrics: adt {
+ pagew: int;
+ dpi: int;
+ em: int; # size in dots
+ en: int; # size in dots
+ V: int; # font height in dots
+ indent: int;
+ ssindent: int;
+ };
+
+ Text: adt {
+ font: int;
+ attr: int;
+ text: string;
+ heading: int; # heading level
+ link: string;
+ };
+
+ # Text fonts and attributes
+ FONT_ROMAN,
+ FONT_ITALIC,
+ FONT_BOLD: con iota;
+ ATTR_SMALL, ATTR_LAST: con 1 << iota;
+
+ init: fn(): string;
+ parseman: fn[T](fd: ref Sys->FD, metrics: Metrics, ql: int, t: T, setline: chan of list of (int, Text))
+ for{
+ T =>
+ textwidth: fn(t: self T, text: Text): int;
+ };
+};
+
+Man: module {
+ PATH: con "/dis/man.dis";
+
+ loadsections: fn(sections: list of string): string;
+ getfiles: fn(sections: list of string , keys: list of string): list of (int, string, string);
+};
diff --git a/module/math.m b/module/math.m
new file mode 100644
index 00000000..4640ecfa
--- /dev/null
+++ b/module/math.m
@@ -0,0 +1,91 @@
+Math: module
+{
+ PATH: con "$Math";
+
+ Infinity: con 1e400;
+ NaN: con 0./0.;
+ MachEps: con 2.2204460492503131e-16;
+ Pi: con 3.14159265358979323846;
+ Degree: con Pi/180.;
+ INVAL: con (1<<0);
+ ZDIV: con (1<<1);
+ OVFL: con (1<<2);
+ UNFL: con (1<<3);
+ INEX: con (1<<4);
+ RND_NR: con (0<<8);
+ RND_NINF: con (1<<8);
+ RND_PINF: con (2<<8);
+ RND_Z: con (3<<8);
+ RND_MASK: con (3<<8);
+ acos: fn(x: real): real; # arccos(x) in [0,pi]
+ acosh: fn(x: real): real;
+ asin: fn(x: real): real; # arcsin(x) in [-pi/2,pi/2]
+ asinh: fn(x: real): real;
+ atan: fn(x: real): real; # arctan(x) in [-pi/2,pi/2]
+ atan2: fn(y, x: real): real; # arctan(y/x) in [-pi,pi]
+ atanh: fn(x: real): real;
+ cbrt: fn(x: real): real;
+ ceil: fn(x: real): real;
+ copysign: fn(x, s: real): real;
+ cos: fn(x: real): real;
+ cosh: fn(x: real): real;
+ dot: fn(x, y: array of real): real;
+ erf: fn(x: real): real;
+ erfc: fn(x: real): real;
+ exp: fn(x: real): real;
+ expm1: fn(x: real): real;
+ fabs: fn(x: real): real;
+ fdim, fmin, fmax: fn(x, y: real): real;
+ finite: fn(x: real): int;
+ floor: fn(x: real): real;
+ fmod: fn(x, y: real): real;
+ gemm: fn(transa, transb: int, # upper case N or T
+ m, n, k: int, alpha: real,
+ a: array of real, lda: int,
+ b: array of real, ldb: int, beta: real,
+ c: array of real, ldc: int);
+ getFPcontrol, getFPstatus: fn(): int;
+ FPcontrol, FPstatus: fn(r, mask: int): int;
+ hypot: fn(x, y: real): real;
+ iamax: fn(x: array of real): int;
+ ilogb: fn(x: real): int;
+ isnan: fn(x: real): int;
+ j0: fn(x: real): real;
+ j1: fn(x: real): real;
+ jn: fn(n: int, x: real): real;
+ lgamma: fn(x: real): (int,real);
+ log: fn(x: real): real;
+ log10: fn(x: real): real;
+ log1p: fn(x: real): real;
+ modf: fn(x: real): (int,real);
+ nextafter: fn(x, y: real): real;
+ norm1, norm2: fn(x: array of real): real;
+ pow: fn(x, y: real): real;
+ pow10: fn(p: int): real;
+ remainder: fn(x, p: real): real;
+ rint: fn(x: real): real;
+ scalbn: fn(x: real, n: int): real;
+ sin: fn(x: real): real;
+ sinh: fn(x: real): real;
+ sort: fn(x: array of real, pi: array of int);
+ sqrt: fn(x: real): real;
+ tan: fn(x: real): real;
+ tanh: fn(x: real): real;
+ y0: fn(x: real): real;
+ y1: fn(x: real): real;
+ yn: fn(n: int, x: real): real;
+
+
+ import_int: fn(b: array of byte, x: array of int);
+ import_real32: fn(b: array of byte, x: array of real);
+ import_real: fn(b: array of byte, x: array of real);
+ export_int: fn(b: array of byte, x: array of int);
+ export_real32: fn(b: array of byte, x: array of real);
+ export_real: fn(b: array of byte, x: array of real);
+
+ # undocumented, of specialized interest only DEPRECATED
+ bits32real: fn(b: int): real; # IEEE 32-bit format to real
+ bits64real: fn(b: big): real; # IEEE 64-bit format to real
+ realbits32: fn(x: real): int; # real to IEEE 32-bit format
+ realbits64: fn(x: real): big; # real to IEEE 64-bit format
+};
diff --git a/module/math/geodesy.m b/module/math/geodesy.m
new file mode 100644
index 00000000..77ae1af0
--- /dev/null
+++ b/module/math/geodesy.m
@@ -0,0 +1,58 @@
+Geodesy: module
+{
+ PATH: con "/dis/math/geodesy.dis";
+
+ # easting, northing in metres
+ Eano: adt{
+ e: real;
+ n: real;
+ };
+
+ # latitude, longitude in radians
+ Lalo: adt{
+ la: real;
+ lo: real;
+ };
+
+ # datums
+ # WGS84 and ITRS2000 effectively the same
+ OSGB36, Ireland65, ED50, WGS84, ITRS2000, ETRS89: con iota;
+
+ # transverse Mercator projections
+ Natgrid, IrishNatgrid, UTMEur, UTM: con iota;
+
+ # call first
+ # d specifies the datum (default WGS84)
+ # t specifies the transverse Mercator projection (default Natgrid)
+ # z specifies the UTM zone if relevant (default 30)
+ # calls format below
+ init: fn(d: int, t: int, z: int);
+
+ # alters the current datum, transverse Mercator projection and UTM zone
+ # use a negative value to leave unaltered
+ format: fn(d: int, t: int, z: int);
+
+ # OS string to (easting, northing) and back
+ # formats XYen, XYeenn, XYeeennn, XYeeeennnn, XYeeeeennnnn or
+ # formats eenn, eeennn, eeeennnn, eeeeennnnn, eeeeeennnnnn
+ os2en: fn(s: string): (int, Eano); # returns (0, ...) if bad string format
+ en2os: fn(en: Eano): string;
+
+ # latitude/longitude string to (latitude, longitude) and back
+ # format latitude longitude
+ # formats deg[N|S], deg:min[N|S], deg:min:sec[N|S] for latitude
+ # formats deg[E|W], deg:min[E|W], deg:min:sec[E|W] for longitude
+ str2lalo: fn(s: string): (int, Lalo); # returns (0, ...) if bad string format
+ lalo2str: fn(lalo: Lalo): string;
+
+ # general string to (easting, northing)
+ # OS grid or latitude/longitude format as above
+ str2en: fn(s: string): (int, Eano); # returns (0, ...) if bad string format
+
+ # (easting, northing) to (latitude, longitude) and back
+ en2lalo: fn(en: Eano): Lalo;
+ lalo2en: fn(lalo: Lalo): Eano;
+
+ # approximate transformations between any of OSGB36, WGS84, ITRS2000, ETRS89
+ datum2datum: fn(lalo: Lalo, f: int, t: int): Lalo;
+};
diff --git a/module/math/polyfill.m b/module/math/polyfill.m
new file mode 100644
index 00000000..be9af8db
--- /dev/null
+++ b/module/math/polyfill.m
@@ -0,0 +1,18 @@
+Polyfill: module
+{
+ PATH: con "/dis/math/polyfill.dis";
+
+ Zstate: adt{
+ r: Draw->Rect;
+ zbuf0, zbuf1: array of int;
+ xlen: int;
+ ylen: int;
+ xylen: int;
+ };
+
+ init: fn();
+ initzbuf: fn(r: Draw->Rect): ref Zstate;
+ clearzbuf: fn(s: ref Zstate);
+ setzbuf: fn(s: ref Zstate, zd: int);
+ fillpoly: fn(d: ref Image, v: array of Point, w: int, s: ref Image, p: Point, zstate: ref Zstate, dc, dx, dy: int);
+}; \ No newline at end of file
diff --git a/module/math/polyhedra.m b/module/math/polyhedra.m
new file mode 100644
index 00000000..2b3e9ce6
--- /dev/null
+++ b/module/math/polyhedra.m
@@ -0,0 +1,25 @@
+Polyhedra: module
+{
+ PATH: con "/dis/math/polyhedra.dis";
+
+ Vector: adt{
+ x, y, z: real;
+ };
+
+ Polyhedron: adt{
+ name, dname: string;
+ indx, V, E, F, concave, anti, allf, adj: int;
+ v, f: array of Vector;
+ fv, vf: array of array of int;
+ offset: big;
+ prv, nxt: cyclic ref Polyhedron;
+ inc: real;
+ };
+
+ # read in details of all polyhedra in the given file
+ scanpolyhedra: fn(f: string): (int, ref Polyhedron, ref Bufio->Iobuf);
+ # read in the coordinates of all polyhedra
+ getpolyhedra: fn(p: ref Polyhedron, b: ref Bufio->Iobuf);
+ # read in the coordinates of the given polyhedron
+ getpolyhedron: fn(p: ref Polyhedron, b: ref Bufio->Iobuf);
+};
diff --git a/module/memfs.m b/module/memfs.m
new file mode 100644
index 00000000..96566af5
--- /dev/null
+++ b/module/memfs.m
@@ -0,0 +1,5 @@
+MemFS : module {
+ PATH : con "/dis/lib/memfs.dis";
+ init : fn() : string;
+ newfs : fn (maxsz : int) : ref Sys->FD;
+};
diff --git a/module/mpeg.m b/module/mpeg.m
new file mode 100644
index 00000000..c6847b26
--- /dev/null
+++ b/module/mpeg.m
@@ -0,0 +1,13 @@
+#
+# This module has a primitive interface to the
+# mpeg device driver
+#
+Mpeg: module
+{
+ PATH: con "/dis/lib/mpeg.dis";
+
+ play: fn(d: ref Draw->Display, w: ref Image, dopaint: int,
+ r: Draw->Rect, file: string, notify: chan of string): string;
+ ctl: fn(msg: string): int;
+ keycolor: fn(d: ref Draw->Display): ref Draw->Image;
+};
diff --git a/module/multistyx.m b/module/multistyx.m
new file mode 100644
index 00000000..f1c380b2
--- /dev/null
+++ b/module/multistyx.m
@@ -0,0 +1,8 @@
+Multistyx: module {
+ PATH: con "/dis/lib/multistyx.dis";
+ init: fn(): Styxlib;
+ srv: fn(addr, mntpath: string, doauth: int, algs: list of string):
+ (chan of (int, ref Styxlib->Styxserver, string),
+ chan of (int, ref Styxlib->Styxserver, ref Styxlib->Tmsg),
+ string);
+};
diff --git a/module/muxclient.m b/module/muxclient.m
new file mode 100644
index 00000000..504c2a4c
--- /dev/null
+++ b/module/muxclient.m
@@ -0,0 +1,23 @@
+Muxclient: module
+{
+ # From appl to mux
+ AMexit: con 10; # application is exiting
+ AMstartir: con 11; # application is ready to receive IR events
+ AMstartkbd: con 12; # application is ready to receive keyboard characters
+ AMstartptr: con 13; # application is ready to receive mouse events
+ AMnewpin: con 14; # application needs a PIN
+
+ # From mux to appl
+ MAtop: con 20; # application should make all its windows visible
+
+ Context: adt
+ {
+ screen: ref Screen; # place to make windows
+ display: ref Display; # frame buffer on which windows reside
+ cir: chan of int; # incoming events from IR remote
+ ckbd: chan of int; # incoming characters from keyboard
+ cptr: chan of ref Pointer; # incoming stream of mouse positions
+ ctoappl: chan of int; # commands from mux to application
+ ctomux: chan of int; # commands from application to mux
+ };
+};
diff --git a/module/names.m b/module/names.m
new file mode 100644
index 00000000..5c17ff77
--- /dev/null
+++ b/module/names.m
@@ -0,0 +1,13 @@
+Names: module
+{
+ PATH: con "/dis/lib/names.dis";
+
+ cleanname: fn(name: string): string;
+ dirname: fn(name: string): string;
+ basename: fn(name: string, suffix: string): string;
+ elements: fn(name: string): list of string;
+ isprefix: fn(a: string, b: string): int;
+ pathname: fn(els: list of string): string;
+ rooted: fn(root: string, name: string): string;
+ relative: fn(name: string, root: string): string;
+};
diff --git a/module/newns.m b/module/newns.m
new file mode 100644
index 00000000..e7c0c23e
--- /dev/null
+++ b/module/newns.m
@@ -0,0 +1,8 @@
+Newns: module
+{
+ PATH: con "/dis/lib/newns.dis";
+ #
+ # Build a new namespace from a description file
+ #
+ newns: fn(user: string, nsfile: string): string;
+};
diff --git a/module/palm.m b/module/palm.m
new file mode 100644
index 00000000..9e463c59
--- /dev/null
+++ b/module/palm.m
@@ -0,0 +1,213 @@
+Palm: module {
+
+ #
+ # basic Palm data types
+ #
+
+ PATH: con "/dis/lib/palm.dis";
+
+ DBInfo: adt {
+ name: string;
+ attr: int;
+ dtype: string; # database type (byte[4])
+ version: int; # defined by application
+ creator: string; # creating application (byte[4])
+ ctime: int;
+ mtime: int;
+ btime: int; # last backup
+ modno: int; # modification number: set to zero
+ uidseed: int; # unique record ID seed (unused, set to zero)
+
+ # the following is used by the database access protocol
+ index: int;
+
+ new: fn(name: string, attr: int, dtype: string, version: int, creator: string): ref DBInfo;
+ };
+
+ # file attributes:
+
+ Fresource: con 1<<0; # file is .prc not .pdb
+ Fronly: con 1<<1; # read only
+ Fappinfodirty: con 1<<2;
+ Fbackup: con 1<<3; # no conduit exists
+ Foverwrite: con 1<<4; # overwrite older copy if present
+ Freset: con 1<<5; # reset after installation
+ Fprivate: con 1<<6; # don't allow copy of this to be beamed
+ Fstream: con 1<<7; # file is an array of bytes, not a database
+
+ # extended (misc) attributes for Desklink->ReadDBList
+ Fnosync: con (1<<7)<<16;
+ Frambased: con (1<<6)<<16;
+
+ Noindex: con 16rFFFF; # unknown index
+
+ Record: adt {
+ id: int; # unique record ID (24 bits)
+ attr: int; # record attributes
+ cat: int; # category
+ data: array of byte;
+
+ new: fn(id: int, attr: int, cat: int, size: int): ref Record;
+ };
+
+ # Record.attr values:
+
+ Rdelete: con 16r80; # delete next sync
+ Rdirty: con 16r40; # record modified
+ Rinuse: con 16r20; # record in use
+ Rsecret: con 16r10; # record is secret
+ Rarchive: con 16r08; # archive next sync
+ Rmcat: con 16r0F; # mask for category field in Palmdb->Entry.attrs
+
+ Resource: adt {
+ name: int; # byte[4]: resource name or type
+ id: int; # resource ID (16 bits)
+ data: array of byte;
+
+ new: fn(name: int, id: int, size: int): ref Resource;
+ };
+
+ # common form of category data in appinfo
+ Categories: adt {
+ renamed: int; # which categories have been renamed
+ labels: array of string; # 16 category names
+ uids: array of int; # corresponding unique IDs
+ lastuid: int; # last unique ID assigned
+ appdata: array of byte; # remaining data is application-specific
+
+ new: fn(labels: array of string): ref Categories;
+ unpack: fn(a: array of byte): ref Categories;
+ pack: fn(c: self ref Categories): array of byte;
+ mkidmap: fn(c: self ref Categories): array of int;
+ };
+
+ Doc: adt {
+ m: Palmdb;
+ file: ref Palmdb->PDB;
+ version: int;
+ length: int; # uncompressed
+ nrec: int; # text records only
+ recsize: int; # uncompressed
+ position: int;
+ sizes: array of int; # sizes of uncompressed records
+
+ open: fn(m: Palmdb, file: ref Palmdb->PDB): (ref Doc, string);
+ read: fn(nil: self ref Doc, i: int): (string, string);
+ iscompressed: fn(nil: self ref Doc): int;
+ unpacktext: fn(d: self ref Doc, a: array of byte): (string, string);
+ textlength: fn(d: self ref Doc, a: array of byte): int;
+ };
+
+ init: fn(): string;
+
+ # name mapping
+ filename: fn(s: string): string;
+ dbname: fn(s: string): string;
+
+ # convert between resource/application ID and string
+ id2s: fn(id: int): string;
+ s2id: fn(s: string): int;
+
+ # time conversion
+ pilot2epoch: fn(t: int): int;
+ epoch2pilot: fn(t: int): int;
+
+ # Latin-1 to string conversion
+ gets: fn(a: array of byte): string;
+ puts: fn(a: array of byte, s: string);
+
+ # big-endian conversion
+ get2: fn(a: array of byte): int;
+ get3: fn(a: array of byte): int;
+ get4: fn(a: array of byte): int;
+ put2: fn(a: array of byte, v: int);
+ put3: fn(a: array of byte, v: int);
+ put4: fn(a: array of byte, v: int);
+
+ # argument wrapping for Desklink and CMP 2.x
+ ArgIDbase: con 16r20; # first argument ID
+ argsize: fn(args: array of (int, array of byte)): int;
+ packargs: fn(out: array of byte, args: array of (int, array of byte)): array of byte;
+ unpackargs: fn(argc: int, reply: array of byte): (array of (int, array of byte), string);
+
+};
+
+Palmdb: module {
+
+ PATH: con "/dis/lib/palmdb.dis";
+
+ DB: adt {
+ x: int; # instance index, used internally
+
+ mode: int;
+ attr: int; # essential database attributes
+
+ open: fn(nil: string, mode: int): (ref DB, string);
+ create: fn(nil: string, mode: int, perm: int, nil: ref Palm->DBInfo): (ref DB, string);
+ close: fn(nil: self ref DB): string;
+
+ stat: fn(nil: self ref DB): ref Palm->DBInfo;
+ wstat: fn(nil: self ref DB, nil: ref Palm->DBInfo, flags: int);
+
+ rdappinfo: fn(nil: self ref DB): (array of byte, string);
+ wrappinfo: fn(nil: self ref DB, nil: array of byte): string;
+
+ rdsortinfo: fn(nil: self ref DB): (array of int, string);
+ wrsortinfo: fn(nil: self ref DB, nil: array of int): string;
+
+ readidlist: fn(nil: self ref DB, sort: int): array of int;
+ nentries: fn(nil: self ref DB): int;
+ resetsyncflags: fn(nil: self ref DB): string;
+
+ records: fn(nil: self ref DB): ref PDB;
+ resources: fn(nil: self ref DB): ref PRC;
+ };
+
+ # database files (.pdb, .doc, and most others)
+ PDB: adt {
+ db: ref DB;
+
+ read: fn(nil: self ref PDB, index: int): ref Palm->Record;
+ readid: fn(nil: self ref PDB, id: int): (ref Palm->Record, int);
+
+ resetnext: fn(nil: self ref PDB): int;
+ readnextmod: fn(nil: self ref PDB): (ref Palm->Record, int);
+# DLP 1.1 functions:
+# readnextincat(nil: self ref DB, cat: int): (ref Palm->Record, string);
+# readnextmodincat(nil: self ref DB, cat: int): (ref Palm->Record, string);
+
+ write: fn(nil: self ref PDB, r: ref Palm->Record): string;
+
+ truncate: fn(nil: self ref PDB): string;
+ delete: fn(nil: self ref PDB, id: int): string;
+ deletecat: fn(nil: self ref PDB, cat: int): string;
+ purge: fn(nil: self ref PDB): string;
+
+ movecat: fn(nil: self ref PDB, old: int, new: int): string;
+
+ };
+
+ # resource files (.prc)
+ PRC: adt {
+ db: ref DB;
+
+ # read by index, or by type & id
+ read: fn(nil: self ref PRC, index: int): ref Palm->Resource;
+ readtype: fn(nil: self ref PRC, name: int, id: int): (ref Palm->Resource, int);
+
+ # write by type and id only (desklink)
+ write: fn(nil: self ref PRC, r: ref Palm->Resource): string;
+
+ truncate: fn(nil: self ref PRC): string;
+ delete: fn(nil: self ref PRC, name: int, id: int): string;
+ };
+
+ # open modes (not the same as Sys->)
+ OREAD: con 16r80;
+ OWRITE: con 16r40;
+ ORDWR: con OREAD|OWRITE;
+ OEXCL: con 16r20;
+ OSECRET: con 16r10;
+
+ init: fn(m: Palm): string;
+};
diff --git a/module/palmfile.m b/module/palmfile.m
new file mode 100644
index 00000000..e7467690
--- /dev/null
+++ b/module/palmfile.m
@@ -0,0 +1,140 @@
+Palmfile: module {
+
+ PATH: con "/dis/lib/palmfile.dis";
+
+ DBInfo: adt {
+ name: string;
+ attr: int;
+ dtype: string; # database type (byte[4])
+ version: int; # defined by application
+ creator: string; # creating application (byte[4])
+ ctime: int;
+ mtime: int;
+ btime: int; # last backup
+ modno: int; # modification number: set to zero
+ uidseed: int; # unique record ID seed (unused, set to zero)
+
+ # used internally and by the database access protocol
+ appinfo: int; # AppInfo offset
+ sortinfo: int; # SortInfo offset
+
+ # the following are used by the database access protocol
+ index: int;
+ more: int;
+
+ new: fn(name: string, attr: int, dtype: string, version: int, creator: string): ref DBInfo;
+ };
+
+ # file attributes:
+
+ Fresource: con 1<<0; # file is .prc not .pdb
+ Fronly: con 1<<1; # read only
+ Fappinfodirty: con 1<<2;
+ Fbackup: con 1<<3; # no conduit exists
+ Foverwrite: con 1<<4; # overwrite older copy if present
+ Freset: con 1<<5; # reset after installation
+ Fprivate: con 1<<6; # don't allow copy of this to be beamed
+
+ Record: adt {
+ id: int; # resource: ID; data: unique record ID
+ index: int;
+ name: int; # byte[4]: resource record only
+ attr: int; # data record only
+ cat: int; # category
+ data: array of byte;
+
+# new: fn(size: int): ref Record;
+ };
+
+ Entry: adt {
+ id: int; # resource: id; record: unique ID
+ offset: int;
+ size: int;
+ name: int; # resource entry only
+ attr: int; # record entry only
+ };
+
+ # record attributes:
+
+ Rdelete: con 16r80; # delete next sync
+ Rdirty: con 16r40; # record modified
+ Rinuse: con 16r20; # record in use
+ Rsecret: con 16r10; # record is secret
+ Rarchive: con 16r08; # archive next sync
+ Rmcat: con 16r0F; # mask for category field in Entry.attrs
+
+ # common form of category data in appinfo
+ Categories: adt {
+ renamed: int; # which categories have been renamed
+ labels: array of string; # 16 category names
+ uids: array of int; # corresponding unique IDs
+ lastuid: int; # last unique ID assigned
+ appdata: array of byte; # remaining data is application-specific
+
+ new: fn(labels: array of string): ref Categories;
+ unpack: fn(a: array of byte): ref Categories;
+ pack: fn(c: self ref Categories): array of byte;
+ mkidmap: fn(c: self ref Categories): array of int;
+ };
+
+ Pfile: adt {
+ fname: string;
+ f: ref Bufio->Iobuf;
+ mode: int;
+
+ info: ref DBInfo;
+ appinfo: array of byte;
+ sortinfo: array of int;
+
+ uidseed: int;
+ entries: array of ref Entry;
+
+ open: fn(nil: string, mode: int): (ref Pfile, string);
+# create: fn(nil: string, mode: int, perm: int, nil: ref DBInfo): ref Pfile;
+ close: fn(nil: self ref Pfile): int;
+
+ stat: fn(nil: self ref Pfile): ref DBInfo;
+# wstat: fn(nil: self ref Pfile, nil: ref DBInfo);
+
+ read: fn(nil: self ref Pfile, index: int): (ref Record, string);
+# readid: fn(nil: self ref Pfile, nil: int): (ref Record, string);
+# append: fn(nil: self ref Pfile, r: ref Record): int;
+
+# setappinfo: fn(nil: self ref Pfile, nil: array of byte);
+# setsortinfo: fn(nil: self ref Pfile, nil: array of int);
+ };
+
+ Doc: adt {
+ file: ref Pfile;
+ version: int;
+ length: int; # uncompressed
+ nrec: int; # text records only
+ recsize: int; # uncompressed
+ position: int;
+ sizes: array of int; # sizes of uncompressed records
+
+ open: fn(file: ref Pfile): (ref Doc, string);
+ read: fn(nil: self ref Doc, i: int): (string, string);
+ iscompressed: fn(nil: self ref Doc): int;
+ unpacktext: fn(d: self ref Doc, a: array of byte): (string, string);
+ textlength: fn(d: self ref Doc, a: array of byte): int;
+ };
+
+ init: fn(): string;
+
+ # name mapping
+ filename: fn(s: string): string;
+ dbname: fn(s: string): string;
+
+ # Latin-1 to string conversion
+ gets: fn(a: array of byte): string;
+ puts: fn(a: array of byte, s: string);
+
+ # big-endian conversion
+ get2: fn(a: array of byte): int;
+ get3: fn(a: array of byte): int;
+ get4: fn(a: array of byte): int;
+ put2: fn(a: array of byte, v: int);
+ put3: fn(a: array of byte, v: int);
+ put4: fn(a: array of byte, v: int);
+};
diff --git a/module/pkcs.m b/module/pkcs.m
new file mode 100644
index 00000000..cf164e59
--- /dev/null
+++ b/module/pkcs.m
@@ -0,0 +1,176 @@
+#
+# Public-Key Cryptography Standards (PKCS)
+#
+# Ref: http://www.rsa.com
+# RFC1423
+#
+
+PKCS: module {
+
+ PATH: con "/dis/lib/crypt/pkcs.dis";
+
+ init: fn(): string;
+
+ # PKCS Object Identifiers
+
+ objIdTab : array of ASN1->Oid;
+
+ id_pkcs,
+ id_pkcs_1,
+ id_pkcs_rsaEncryption,
+ id_pkcs_md2WithRSAEncryption,
+ id_pkcs_md4WithRSAEncryption,
+ id_pkcs_md5WithRSAEncryption,
+ id_pkcs_3,
+ id_pkcs_dhKeyAgreement,
+ id_pkcs_5,
+ id_pkcs_pbeWithMD2AndDESCBC,
+ id_pkcs_pbeWithMD5AndDESCBC,
+ id_pkcs_7,
+ id_pkcs_data,
+ id_pkcs_singnedData,
+ id_pkcs_envelopedData,
+ id_pkcs_signedAndEnvelopedData,
+ id_pkcs_digestData,
+ id_pkcs_encryptedData,
+ id_pkcs_9,
+ id_pkcs_emailAddress,
+ id_pkcs_unstructuredName,
+ id_pkcs_contentType,
+ id_pkcs_messageDigest,
+ id_pkcs_signingTime,
+ id_pkcs_countersignature,
+ id_pkcs_challengePassword,
+ id_pkcs_unstructuredAddress,
+ id_pkcs_extCertAttrs,
+ id_algorithm_shaWithDSS : con iota;
+
+ # PKCS1
+
+ RSAParams: adt {
+ modulus : ref Keyring->IPint;
+ exponent : ref Keyring->IPint;
+ };
+
+ RSAKey: adt {
+ modulus : ref Keyring->IPint;
+ modlen : int;
+ exponent : ref Keyring->IPint;
+
+ bits: fn(k: self ref RSAKey): int;
+ #tostring: fn(k: self ref RSAKey): string;
+ };
+
+ MD2_WithRSAEncryption : con 0;
+ MD5_WithRSAEncryption : con 1;
+
+ rsa_encrypt: fn(data: array of byte, key: ref RSAKey, blocktype: int): (string, array of byte);
+ rsa_decrypt: fn(data: array of byte, key: ref RSAKey, public: int): (string, array of byte);
+ rsa_sign: fn(data: array of byte, sk: ref RSAKey, algid: int): (string, array of byte);
+ rsa_verify: fn(data, signature: array of byte, pk: ref RSAKey, algid: int): int;
+ decode_rsapubkey: fn(a: array of byte): (string, ref RSAKey);
+
+ # Note:
+ # DSS included here is only for completeness.
+
+ DSSParams: adt {
+ p : ref Keyring->IPint;
+ q : ref Keyring->IPint;
+ alpha : ref Keyring->IPint;
+ };
+
+ DSSPublicKey: adt {
+ params : ref DSSParams;
+ y : ref Keyring->IPint;
+ };
+
+ DSSPrivateKey: adt {
+ params : ref DSSParams;
+ x : ref Keyring->IPint;
+ };
+
+ generateDSSKeyPair: fn(strength: int): (ref DSSPublicKey, ref DSSPrivateKey);
+ dss_sign: fn(a: array of byte, sk: ref DSSPrivateKey): (string, array of byte);
+ dss_verify: fn(a, signa: array of byte, pk: ref DSSPublicKey): int;
+ decode_dsspubkey: fn(a: array of byte): (string, ref DSSPublicKey);
+
+ # PKCS3
+
+ DHParams: adt {
+ prime : ref Keyring->IPint; # prime (p)
+ base : ref Keyring->IPint; # generator (alpha)
+ privateValueLength : int;
+ };
+
+ DHPublicKey: adt {
+ param : ref DHParams;
+ pk : ref Keyring->IPint;
+ };
+
+ DHPrivateKey: adt {
+ param : ref DHParams;
+ pk : ref Keyring->IPint;
+ sk : ref Keyring->IPint;
+ };
+
+ generateDHParams: fn(primelen: int): ref DHParams;
+ setupDHAgreement: fn(dh: ref DHParams): (ref DHPrivateKey, ref DHPublicKey);
+ computeDHAgreedKey: fn(dh: ref DHParams, mysk, upk: ref Keyring->IPint): array of byte;
+ decode_dhpubkey: fn(a: array of byte): (string, ref DHPublicKey);
+
+ # PKCS5
+
+ PBEParams: adt {
+ salt : array of byte; # [8]
+ iterationCount : int;
+ };
+
+ PBE_MD2_DESCBC : con 0;
+ PBE_MD5_DESCBC : con 1;
+
+ generateDESKey: fn(pw: array of byte, param: ref PBEParams, alg: int)
+ : (ref Keyring->DESstate, array of byte, array of byte);
+ pbe_encrypt: fn(state: ref Keyring->DESstate, b: array of byte): array of byte;
+ pbe_decrypt: fn(state: ref Keyring->DESstate, eb: array of byte): array of byte;
+
+ # PKCS6
+
+ ExtCertInfo: adt {
+ version : int;
+ cert : array of byte; # der encoded x509 Certificate
+ attrs : list of array of byte; # attribute as array of byte
+ };
+
+ # PKCS7
+ # See module X509
+
+ # PKCS8
+
+ PrivateKeyInfo: adt { # as SEQUENCE
+ version : int; # should be 0
+ privateKeyAlgorithm : ref AlgIdentifier;
+ privateKey : array of byte; # octet string
+ attrs : list of array of byte; # [0] IMPLICIT Attributes OPTIONAL
+
+ encode: fn(p: self ref PrivateKeyInfo): (string, array of byte);
+ decode: fn(a: array of byte): (string, ref PrivateKeyInfo);
+ };
+
+ EncryptedPrivateKeyInfo: adt { # as SEQUENCE
+ encryptionAlgorithm : ref AlgIdentifier;
+ encryptedData : array of byte; # octet string
+
+ encode: fn(ep: self ref EncryptedPrivateKeyInfo): (string, array of byte);
+ decode: fn(a: array of byte): (string, ref EncryptedPrivateKeyInfo);
+ };
+
+ AlgIdentifier: adt { # TODO: move this to ASN1
+ oid : ref ASN1->Oid;
+ parameter : array of byte;
+ };
+
+ # PKCS10
+ # See module X509
+};
+
+
diff --git a/module/plumbmsg.m b/module/plumbmsg.m
new file mode 100644
index 00000000..cec82b51
--- /dev/null
+++ b/module/plumbmsg.m
@@ -0,0 +1,44 @@
+Plumbmsg: module
+{
+ PATH: con "/dis/lib/plumbmsg.dis";
+
+ # Message format:
+ # source application\n
+ # destination application\n
+ # working directory\n
+ # type\n
+ # properties\n
+ # nbytes\n
+ # n bytes
+
+ Msg: adt
+ {
+ src: string;
+ dst: string;
+ dir: string;
+ kind: string;
+ attr: string;
+ data: array of byte;
+
+ # used by applications
+ send: fn(msg: self ref Msg): int;
+ recv: fn(): ref Msg;
+
+ # used by plumb and send, recv
+ pack: fn(msg: self ref Msg): array of byte;
+ unpack: fn(b: array of byte): ref Msg;
+ };
+
+ Attr: adt
+ {
+ name: string;
+ val: string;
+ };
+
+ init: fn(doinput: int, rcvport: string, maxdata: int): int;
+ shutdown: fn();
+
+ string2attrs: fn(s: string): list of ref Attr;
+ attrs2string: fn(l: list of ref Attr): string;
+ lookup: fn(attrs: list of ref Attr, name: string): (int, string);
+};
diff --git a/module/pop3.m b/module/pop3.m
new file mode 100644
index 00000000..a0066550
--- /dev/null
+++ b/module/pop3.m
@@ -0,0 +1,40 @@
+# pop3 protocol independent access to an email server.
+
+Pop3: module
+{
+ PATH: con "/dis/lib/pop3.dis";
+
+ # all functions return status (-ve when error)
+
+ # open a connection with the pop3 server
+ # requires the email server's name or address or nil if a default server is to be used
+ # returns (status, errror string)
+ open: fn(user, password, server: string) : (int, string);
+
+ # stat the user's mailbox
+ # returns (status, error string, no. messages, total no. bytes)
+ stat: fn(): (int, string, int, int);
+
+ # list the user's mailbox
+ # returns (status, error string, list of (message no., bytes in message))
+ msglist: fn(): (int, string, list of (int, int));
+
+ # list as above but return (status, error string, list of message nos.)
+ msgnolist: fn(): (int, string, list of int);
+
+ # top of a message given it's no.
+ # returns (status, error string, message top)
+ top: fn(m: int) : (int, string, string);
+
+ # full text of a message given it's no.
+ # returns (status, error string, message)
+ get: fn(m: int) : (int, string, string);
+
+ # delete a message given it's no.
+ # returns (status, error string)
+ delete: fn(m: int) : (int, string);
+
+ # close the connection
+ # returns (status, error string)
+ close: fn(): (int, string);
+};
diff --git a/module/popup.m b/module/popup.m
new file mode 100644
index 00000000..f8773acc
--- /dev/null
+++ b/module/popup.m
@@ -0,0 +1,11 @@
+# pop-up menus.
+# use choicebuttons instead - it's difficult to get these right.
+Popup: module {
+ PATH: con "/dis/lib/popup.dis";
+ init: fn();
+# mkbutton: fn(win: ref Tk->Toplevel, w: string, a: array of string, n: int): chan of string;
+# changebutton: fn(win: ref Tk->Toplevel, w: string, a: array of string, n: int);
+# event: fn(win: ref Tk->Toplevel, e: string, a: array of string): int;
+# add: fn(a: array of string, s: string): (array of string, int);
+ post: fn(win: ref Tk->Toplevel, p: Draw->Point, a: array of string, n: int): chan of int;
+};
diff --git a/module/powerman.m b/module/powerman.m
new file mode 100644
index 00000000..8cee00f9
--- /dev/null
+++ b/module/powerman.m
@@ -0,0 +1,8 @@
+Powerman: module
+{
+ PATH: con "/dis/lib/powerman.dis";
+ init: fn(file: string, cmd: chan of string): int;
+ ack: fn(cmd: string);
+ ctl: fn(cmd: string): string;
+ stop: fn();
+};
diff --git a/module/prefab.m b/module/prefab.m
new file mode 100644
index 00000000..95d0f62e
--- /dev/null
+++ b/module/prefab.m
@@ -0,0 +1,113 @@
+Prefab: module
+{
+ PATH: con "$Prefab";
+
+ # types of Elements
+ EIcon: con 0;
+ EText: con 1;
+ ETitle: con 2;
+ EHorizontal: con 3;
+ EVertical: con 4;
+ ESeparator: con 5;
+
+ # first arg to Element.adjust: size of elements
+ Adjpack: con 10; # leave alone, pack tightly
+ Adjequal: con 11; # make equal
+ Adjfill: con 12; # make equal, filling available space
+
+ # second arg: position of element within space
+ Adjleft: con 20;
+ Adjup: con 20;
+ Adjcenter: con 21;
+ Adjright: con 22;
+ Adjdown: con 22;
+
+ # default fonts and colors for objects
+ Style: adt
+ {
+ titlefont: ref Draw->Font;
+ textfont: ref Draw->Font;
+ elemcolor: ref Draw->Image;
+ edgecolor: ref Draw->Image;
+ titlecolor: ref Draw->Image;
+ textcolor: ref Draw->Image;
+ highlightcolor: ref Draw->Image;
+ };
+
+ # drawing environment for objects
+ Environ: adt
+ {
+ screen: ref Draw->Screen;
+ style: ref Style;
+ };
+
+ # operand for layout operators; set either (font, color, text) or (icon, mask)
+ Layout: adt
+ {
+ font: ref Draw->Font;
+ color: ref Draw->Image;
+ text: string;
+ icon: ref Draw->Image;
+ mask: ref Draw->Image;
+ tag: string;
+ };
+
+ # graphical objects in the interface, recursively defined for making lists
+ Element: adt
+ {
+ # part of Ell elements
+ kind: int; # type: EIcon, EText, etc.
+ r: Draw->Rect; # rectangle on screen
+ environ: ref Environ; # graphics screen, style
+ tag: string; # identifier for selection
+
+ # different fields defined for different kinds of Elements
+ kids: list of ref Element; # children of EHorizontal, EVertical
+ str: string; # text in an EText element
+ mask: ref Draw->Image; # part of Eicon, ESeparator
+ image: ref Draw->Image; # part of Eicon, ESeparator, EText, Etitle
+ font: ref Draw->Font; # part of EText, Etitle
+
+ # constructors
+ icon: fn(env: ref Environ, r: Draw->Rect, icon, mask: ref Draw->Image): ref Element;
+ text: fn(env: ref Environ, text: string, r: Draw->Rect, kind: int): ref Element;
+ layout: fn(env: ref Environ, lay: list of Layout, r: Draw->Rect, kind: int): ref Element;
+ elist: fn(env: ref Environ, elem: ref Element, kind: int): ref Element;
+ separator: fn(env: ref Environ, r: Draw->Rect, icon, mask: ref Draw->Image): ref Element;
+
+ # editing and geometry
+ append: fn(elist: self ref Element, elem: ref Element): int;
+ adjust: fn(elem: self ref Element, equal: int, dir: int);
+ clip: fn(elem: self ref Element, r: Draw->Rect);
+ scroll: fn(elem: self ref Element, d: Draw->Point);
+ translate: fn(elem: self ref Element, d: Draw->Point);
+ show: fn(elist: self ref Element, elem: ref Element): int;
+ };
+
+ # connects an element to a window for display
+ Compound: adt
+ {
+ image: ref Draw->Image; # window on which contents are drawn
+ environ: ref Environ; # graphics screen, style
+ r: Draw->Rect; # rectangle on screen
+ title: ref Element; # above the line (may be nil)
+ contents: ref Element; # below the line
+
+ # constructors
+ iconbox: fn(env: ref Environ, p: Draw->Point, title: string, icon, mask: ref Draw->Image): ref Compound;
+ textbox: fn(env: ref Environ, r: Draw->Rect, title, text: string): ref Compound;
+ layoutbox:fn(env: ref Environ, r: Draw->Rect, title: string, lay: list of Layout): ref Compound;
+ box: fn(env: ref Environ, p: Draw->Point, title, elist: ref Element): ref Compound;
+
+ # display
+ draw: fn(comp: self ref Compound);
+ redraw: fn(comp: self ref Compound, r: Draw->Rect);
+ scroll: fn(comp: self ref Compound, elem: ref Element, d: Draw->Point);
+ show: fn(comp: self ref Compound, elem: ref Element): int;
+
+ # support for using EHorizontal and EVertical as menus
+ select: fn(comp: self ref Compound, elem: ref Element, i: int, c: chan of int): (int, int, ref Element);
+ tagselect: fn(comp: self ref Compound, elem: ref Element, i: int, c: chan of int): (int, int, ref Element);
+ highlight: fn(comp: self ref Compound, elem: ref Element, on: int);
+ };
+};
diff --git a/module/print.m b/module/print.m
new file mode 100644
index 00000000..79c5aa8c
--- /dev/null
+++ b/module/print.m
@@ -0,0 +1,88 @@
+Print: module
+{
+ PATH: con "/dis/lib/print/print.dis";
+ CONFIG_PATH: con "/lib/print/";
+
+ init: fn(): int;
+ set_printfd: fn(fd: ref Sys->FD);
+ print_image: fn(p: ref Printer, display: ref Draw->Display, im: ref Draw->Image, pcwidth: int, cancel: chan of int): int;
+ print_textfd: fn(p: ref Printer, fd: ref Sys->FD, ps: real, pr: int, wrap: int): int;
+ get_defprinter: fn(): ref Printer;
+ set_defprinter: fn(p: ref Printer);
+ get_size: fn(p: ref Printer): (int, int, int); # dpi, xpixels, ypixels
+ get_printers: fn(): list of ref Printer;
+ get_papers: fn(): list of ref Paper;
+ save_settings: fn(): int;
+
+ # Printer types
+
+ Ptype: adt {
+ name: string;
+ desc: string;
+ modes: list of ref Pmode;
+ driver: string;
+ hpmapfile: string;
+ };
+
+ # Paper sizes
+
+ Paper: adt {
+ name: string;
+ hpcode: string;
+ width_inches: real;
+ height_inches: real;
+ };
+
+ # Print modes
+
+ Pmode: adt {
+ name: string;
+ desc: string;
+ resx: int;
+ resy: int;
+ blackdepth: int;
+ coldepth: int;
+ blackresmult: int;
+ };
+
+ # Print options
+
+ Popt: adt {
+ name: string;
+ mode: ref Pmode;
+ paper: ref Paper;
+ orientation: int;
+ duplex: int;
+ };
+
+ # Printer instance
+
+ PORTRAIT: con 0;
+ LANDSCAPE: con 1;
+
+ DUPLEX_OFF: con 0;
+ DUPLEX_LONG: con 1;
+ DUPLEX_SHORT: con 2;
+
+ Printer: adt {
+ name: string;
+ ptype: ref Ptype;
+ device: string;
+ popt: ref Popt;
+ pdriver: Pdriver;
+ };
+
+};
+
+
+Pdriver: module
+{
+ PATHPREFIX: con "/dis/lib/print/";
+ DATAPREFIX: con "/lib/print/";
+
+ init: fn(debug: int);
+ sendimage: fn(p: ref Print->Printer, tfd: ref Sys->FD, display: ref Draw->Display, im: ref Draw->Image, width: int, lmargin: int, cancel: chan of int): int;
+ sendtextfd: fn(p: ref Print->Printer, pfd, tfd: ref Sys->FD, ps: real, pr: int, wrap: int): int;
+ printable_pixels: fn(p: ref Print->Printer): (int, int);
+
+};
diff --git a/module/profile.m b/module/profile.m
new file mode 100644
index 00000000..fc0ee687
--- /dev/null
+++ b/module/profile.m
@@ -0,0 +1,78 @@
+Profile: module
+{
+ PATH: con "/dis/lib/profile.dis";
+
+ Range: adt{
+ l: int;
+ u: int;
+ f: int;
+ n: cyclic ref Range;
+ };
+
+ Funprof: adt{
+ name: string;
+ # file: string;
+ line: int;
+ count: int;
+ counte: int;
+ };
+
+ Modprof: adt{
+ name: string;
+ path: string;
+ srcpath: string;
+ rawtab: array of (int, int);
+ linetab: array of int;
+ rngtab: array of ref Range;
+ funtab: array of Funprof;
+ total: int;
+ totals: array of int;
+ coverage: int;
+ };
+
+ Prof: adt{
+ mods: list of Modprof;
+ total: int;
+ totals: array of int;
+ };
+
+ Coverage: type list of (string, int, list of (list of (int, int, int), string));
+
+ # constants to or into second arg of show()
+ MODULE: con 1; # give stats for each module
+ FUNCTION: con 2; # give stats for each function
+ LINE: con 4; # give stats for each line
+ VERBOSE: con 8; # full stats
+ FULLHDR: con 16; # file:lineno: on each line of output
+ FREQUENCY: con 32; # show frequency rather than coverage
+
+ init: fn(): int;
+ lasterror: fn(): string;
+ profile: fn(m: string): int;
+ sample: fn(i: int): int;
+ start: fn(): int;
+ stop: fn(): int;
+ stats: fn() : Prof;
+ show: fn(p: Prof, v: int): int;
+ end: fn(): int;
+
+ # coverage profiling specific functions
+
+ cpstart: fn(pid: int): int;
+ cpstats: fn(rec: int, v: int): Prof;
+ cpfstats: fn(v: int): Prof;
+ cpshow: fn(p: Prof, v: int): int;
+
+ coverage: fn(p: Prof, v: int): Coverage;
+
+ # memory profiling specific functions
+
+ MAIN: con 1;
+ HEAP: con 2;
+ IMAGE: con 4;
+
+ memstart: fn(mem: int): int;
+ memstats: fn(): Prof;
+ memshow: fn(p: Prof, v: int): int;
+
+};
diff --git a/module/pslib.m b/module/pslib.m
new file mode 100644
index 00000000..68b4a75c
--- /dev/null
+++ b/module/pslib.m
@@ -0,0 +1,7 @@
+Pslib : module
+{
+ PATH: con "/dis/lib/pslib.dis";
+
+ init: fn(bufio: Bufio);
+ writeimage: fn(ioutb: ref Bufio->Iobuf, im: ref Draw->Image, dpi: int);
+};
diff --git a/module/quicktime.m b/module/quicktime.m
new file mode 100644
index 00000000..f1ab35c1
--- /dev/null
+++ b/module/quicktime.m
@@ -0,0 +1,73 @@
+#
+# Apple QuickTime File Format
+#
+QuickTime: module
+{
+ PATH: con "/dis/lib/quicktime.dis";
+
+ DEFBUF: con 8192;
+
+ AtomHDR: con 8;
+
+ Tkhdr: adt
+ {
+ version: int;
+ creation: int;
+ modtime: int;
+ trackid: int;
+ timescale: int;
+ duration: int;
+ timeoff: int;
+ priority: int;
+ layer: int;
+ altgrp: int;
+ volume: int;
+ matrix: array of int;
+ width: int;
+ height: int;
+ };
+
+ MvhdrSIZE: con 100;
+ Mvhdr: adt
+ {
+ version: int;
+ create: int;
+ modtime: int;
+ timescale: int;
+ duration: int;
+ rate: int;
+ vol: int;
+ r1: int;
+ r2: int;
+ matrix: array of int;
+ r3: int;
+ r4: int;
+ pvtime: int;
+ posttime: int;
+ seltime: int;
+ seldurat: int;
+ curtime: int;
+ nxttkid: int;
+ };
+
+ # QuickTime descriptor
+ QD: adt
+ {
+ fd: ref sys->FD; # descriptor of QuickTime file
+ buf: array of byte; # buffer
+ nbyte: int; # bytes remaining
+ ptr: int; # buffer pointer
+
+ mvhdr: ref Mvhdr; # movie header desctiptor
+
+ readn: fn(r: self ref QD, b: array of byte, l: int): int;
+ skip: fn(r: self ref QD, size: int): int;
+ skipatom: fn(r: self ref QD, size: int): int;
+ atomhdr: fn(r: self ref QD): (string, int);
+ mvhd: fn(r: self ref QD, l: int): string;
+ trak: fn(r: self ref QD, l: int): string;
+ };
+
+ init: fn();
+ open: fn(file: string): (ref QD, string);
+};
diff --git a/module/rand.m b/module/rand.m
new file mode 100644
index 00000000..02f0d005
--- /dev/null
+++ b/module/rand.m
@@ -0,0 +1,7 @@
+Rand: module
+{
+ PATH: con "/dis/lib/rand.dis";
+ init: fn(seed: int);
+ rand: fn(modulus: int): int;
+ bigrand: fn(modulus: big): big;
+};
diff --git a/module/readdir.m b/module/readdir.m
new file mode 100644
index 00000000..b4917688
--- /dev/null
+++ b/module/readdir.m
@@ -0,0 +1,19 @@
+Readdir: module
+{
+ PATH: con "/dis/lib/readdir.dis";
+
+ # sortkey is one of NAME, ATIME, MTIME, SIZE, or NONE
+ # possibly with DESCENDING or'd in
+
+ NAME, ATIME, MTIME, SIZE, NONE: con iota;
+ DESCENDING: con (1<<5);
+
+ init: fn(path: string, sortkey: int): (array of ref Sys->Dir, int);
+ readall: fn(fd: ref Sys->FD, sortkey: int): (array of ref Sys->Dir, int);
+ sortdir:fn(a: array of ref Sys->Dir, key: int): (array of ref Sys->Dir, int);
+
+ # COMPACT can be or'd into sortkey to preserve only the first
+ # (by depth) of a group of duplicate names in a union
+
+ COMPACT: con (1<<4);
+};
diff --git a/module/regex.m b/module/regex.m
new file mode 100644
index 00000000..f285a524
--- /dev/null
+++ b/module/regex.m
@@ -0,0 +1,38 @@
+Regex: module {
+
+ PATH: con "/dis/lib/regex.dis";
+
+# normally imported identifiers
+
+ Re: type ref Arena;
+ compile: fn(nil:string,nil:int): (Re, string);
+ execute: fn(nil:Re, nil:string): array of (int, int);
+ executese: fn(nil:Re, nil:string, se: (int, int), bol: int, eol: int): array of (int, int);
+
+# internal identifiers, not normally imported
+
+ ALT, CAT, DOT, SET, HAT, DOL, NUL, PCLO, CLO, OPT, LPN, RPN : con (1<<16)+iota;
+
+ refRex : type int; # used instead of ref Rex to avoid circularity
+
+ Set: adt { # character class
+ neg: int; # 0 or 1
+ ascii : array of int; # ascii members, bit array
+ unicode : list of (int,int); # non-ascii char ranges
+ };
+
+ Rex: adt { # node in parse of regex, or state of fsm
+ kind : int; # kind of node: char or ALT, CAT, etc
+ left : refRex; # left descendant
+ right : refRex; # right descendant, or next state
+ set : ref Set; # character class
+ pno : int;
+ };
+
+ Arena: adt { # free store from which nodes are allocated
+ rex : array of Rex;
+ ptr : refRex; # next available space
+ start : refRex; # root of parse, or start of fsm
+ pno : int;
+ };
+};
diff --git a/module/regexutils.m b/module/regexutils.m
new file mode 100644
index 00000000..50935d84
--- /dev/null
+++ b/module/regexutils.m
@@ -0,0 +1,17 @@
+
+include "regex.m";
+ regex: Regex;
+
+RegexUtils: module
+{
+ PATH: con "/dis/lib/regexutils.dis";
+ init: fn();
+
+ match: fn(pattern: Regex->Re, s: string): string;
+ match_mult: fn(pattern: Regex->Re, s: string): array of (int, int);
+ sub: fn(text, pattern, new: string): string;
+ sub_re: fn(text: string, pattern: Regex->Re, new: string): string;
+ subg: fn(text, pattern, new: string): string;
+ subg_re: fn(text: string, pattern: Regex->Re, new: string): string;
+};
+
diff --git a/module/registries.m b/module/registries.m
new file mode 100644
index 00000000..5aaa53f4
--- /dev/null
+++ b/module/registries.m
@@ -0,0 +1,44 @@
+Registries: module {
+ PATH: con "/dis/lib/registries.dis";
+ init: fn();
+
+ Attributes: adt {
+ attrs: list of (string, string);
+
+ get: fn(a: self ref Attributes, attr: string): string;
+ set: fn(a: self ref Attributes, attr, val: string);
+ new: fn(attrs: list of (string, string)): ref Attributes;
+ };
+
+ Attached: adt {
+ fd: ref Sys->FD;
+ signerpkhash: string;
+ localuser: string;
+ remoteuser: string;
+ };
+
+ Service: adt {
+ addr: string; # dial this to connect to the service.
+ attrs: ref Attributes; # information about the nature of the service.
+
+ attach: fn(s: self ref Service, user: string, keydir: string): ref Attached;
+ };
+
+ Registered: adt {
+ addr: string;
+ reg: ref Registry;
+ fd: ref Sys->FD;
+ };
+
+ Registry: adt {
+ dir: string;
+ indexfd: ref Sys->FD;
+
+ new: fn(dir: string): ref Registry;
+ connect: fn(svc: ref Service, user: string, keydir: string): ref Registry;
+ services: fn(r: self ref Registry): (list of ref Service, string);
+ find: fn(r: self ref Registry, a: list of (string, string)): (list of ref Service, string);
+ register: fn(r: self ref Registry, addr: string, attrs: ref Attributes, persist: int): (ref Registered, string);
+ unregister: fn(r: self ref Registry, addr: string): string;
+ };
+};
diff --git a/module/riff.m b/module/riff.m
new file mode 100644
index 00000000..130c71f6
--- /dev/null
+++ b/module/riff.m
@@ -0,0 +1,96 @@
+#
+# Microsoft Resource Interchange File Format
+# with AVI support
+#
+Riff: module
+{
+ PATH: con "/dis/lib/riff.dis";
+
+ DEFBUF: con 8192;
+
+ BI_RGB: con 0;
+ BI_RLE8: con 1;
+ BI_RLE4: con 2;
+ BI_BITFEILD: con 3;
+
+ RGB: adt
+ {
+ r: int;
+ g: int;
+ b: int;
+ };
+
+ Binfosize: con 10*4;
+ Bitmapinfo: adt # Windows bitmap info structure
+ {
+ width: int; # width in pixels
+ height: int; # height in pixels
+ planes: int; # planes of output device (must be 1)
+ bitcount: int; # bits per pixel
+ compression: int; # coding BI_RGB... or IV32 for indeo
+ sizeimage: int; # size in bytes of image
+ xpelpermeter: int; # resolution in pixels per meter
+ ypelpermeter: int;
+ clrused: int; # colors used
+ clrimportant: int; # how fixed is the map
+
+ cmap: array of RGB; # color map
+ };
+
+ AVImainhdr: con 14*4;
+ AVIhdr: adt
+ {
+ usecperframe: int;
+ bytesec: int;
+ flag: int;
+ frames: int;
+ initframes: int;
+ streams: int;
+ bufsize: int;
+ width: int;
+ height: int;
+ };
+
+ AVIstreamhdr: con 2*4 + 10*4;
+ AVIstream: adt
+ {
+ # Stream Header information
+ stype: string;
+ handler: string;
+ flags: int;
+ priority: int;
+ initframes: int;
+ scale: int;
+ rate: int;
+ start: int;
+ length: int;
+ bufsize: int;
+ quality: int;
+ samplesz: int;
+
+ # Stream Format information (decoder specific)
+ fmt: array of byte;
+ binfo: ref Bitmapinfo;
+
+ fmt2binfo: fn(a: self ref AVIstream): string;
+ };
+
+ # Riff descriptor
+ RD: adt
+ {
+ fd: ref sys->FD; # descriptor of RIFF file
+ buf: array of byte; # buffer
+ nbyte: int; # bytes remaining
+ ptr: int; # buffer pointer
+
+ gethdr: fn(r: self ref RD): (string, int);
+ readn: fn(r: self ref RD, b: array of byte, l: int): int;
+ check4: fn(r: self ref RD, code: string): string;
+ avihdr: fn(r: self ref RD): (ref AVIhdr, string);
+ streaminfo: fn(r: self ref RD): (ref AVIstream, string);
+ skip: fn(r: self ref RD, size: int): int;
+ };
+
+ init: fn();
+ open: fn(file: string): (ref RD, string);
+};
diff --git a/module/runt.m b/module/runt.m
new file mode 100644
index 00000000..1021041a
--- /dev/null
+++ b/module/runt.m
@@ -0,0 +1,11 @@
+implement nothing;
+
+include "sys.m";
+include "draw.m";
+include "prefab.m";
+include "tk.m";
+include "math.m";
+include "keyring.m";
+include "loader.m";
+# include "readimage.m";
+include "freetype.m";
diff --git a/module/scoretable.m b/module/scoretable.m
new file mode 100644
index 00000000..2501e4b4
--- /dev/null
+++ b/module/scoretable.m
@@ -0,0 +1,12 @@
+# only used by tetris currently. this interface will change.
+Scoretable: module {
+ PATH: con "/dis/lib/scoretable.dis";
+ Score: adt {
+ user: string;
+ score: int;
+ other: string;
+ };
+ init: fn(port: int, user, name: string, scorefile: string): (int, string);
+ setscore: fn(score: int, other: string): int;
+ scores: fn(): list of Score;
+};
diff --git a/module/scsiio.m b/module/scsiio.m
new file mode 100644
index 00000000..9db153e8
--- /dev/null
+++ b/module/scsiio.m
@@ -0,0 +1,27 @@
+#
+# adapted from /sys/include/disk.h on Plan 9: subject to the Lucent Public License 1.02
+#
+ScsiIO: module
+{
+ PATH: con "/dis/lib/scsiio.dis";
+
+ # SCSI interface
+ Scsi: adt {
+ lock: chan of int;
+ inquire: string;
+ rawfd: ref Sys->FD;
+ nchange: int;
+ changetime: int;
+
+ open: fn(f: string): ref Scsi;
+ rawcmd: fn(s: self ref Scsi, c: array of byte, d: array of byte, io: int): int;
+ cmd: fn(s: self ref Scsi, c: array of byte, d: array of byte, io: int): int;
+ ready: fn(s: self ref Scsi): int;
+ };
+
+ Sread, Swrite, Snone: con iota;
+
+ scsierror: fn(asc: int, ascq: int): string;
+
+ init: fn(verbose: int);
+};
diff --git a/module/secstore.m b/module/secstore.m
new file mode 100644
index 00000000..ef9fa100
--- /dev/null
+++ b/module/secstore.m
@@ -0,0 +1,28 @@
+Secstore: module
+{
+ PATH: con "/dis/lib/secstore.dis";
+
+ Maxfilesize: con 128*1024; # default
+ Maxmsg: con 4096;
+
+ init: fn();
+ privacy: fn(): int;
+ cansecstore: fn(addr: string, user: string): int;
+ mkseckey: fn(pass: string): array of byte;
+ connect: fn(addr: string, user: string, pwhash: array of byte): (ref Sys->Connection, string, string);
+ dial: fn(addr: string): ref Sys->Connection;
+ auth: fn(conn: ref Sys->Connection, user: string, pwhash: array of byte): (string, string);
+ sendpin: fn(conn: ref Sys->Connection, pin: string): int;
+ files: fn(conn: ref Sys->Connection): list of (string, int, string, string, array of byte);
+ getfile: fn(conn: ref Sys->Connection, filename: string, maxsize: int): array of byte;
+ remove: fn(conn: ref Sys->Connection, filename: string): int;
+# putfile: fn(conn: ref Sys->Connection, filename: string, data: array of byte,): int;
+ bye: fn(conn: ref Sys->Connection);
+
+ mkfilekey: fn(pass: string): array of byte;
+ decrypt: fn(a: array of byte, key: array of byte): array of byte;
+# encrypt: fn(a: array of byte, key: array of byte): array of byte;
+ erasekey: fn(a: array of byte);
+
+ lines: fn(file: array of byte): list of array of byte;
+};
diff --git a/module/security.m b/module/security.m
new file mode 100644
index 00000000..59a6c361
--- /dev/null
+++ b/module/security.m
@@ -0,0 +1,59 @@
+#
+# security routines implemented in limbo
+#
+
+
+Virgil: module
+{
+ PATH: con "/dis/lib/virgil.dis";
+
+ virgil: fn(args: list of string): string;
+};
+
+Random: module
+{
+ PATH: con "/dis/lib/random.dis";
+
+ ReallyRandom: con 0;
+ NotQuiteRandom: con 1;
+
+ randomint: fn(which: int): int;
+ randombuf: fn(which, n: int): array of byte;
+};
+
+#
+# secure socket layer emulator
+#
+SSL: module
+{
+ PATH: con "/dis/lib/ssl.dis";
+
+ connect: fn(fd: ref Sys->FD): (string, ref Sys->Connection);
+ secret: fn(c: ref Sys->Connection, secretin, secretout: array of byte): string;
+};
+
+
+#
+# Encrypted Key Exchange protocol
+#
+Login: module
+{
+ PATH: con "/dis/lib/login.dis";
+
+ login: fn(id, password, dest: string): (string, ref Keyring->Authinfo);
+};
+
+#
+# Station To Station protocol
+#
+Auth: module
+{
+ PATH: con "/dis/lib/auth.dis";
+
+ init: fn(): string;
+ server: fn(algs: list of string, ai: ref Keyring->Authinfo, fd: ref Sys->FD, setid: int): (ref Sys->FD, string);
+ client: fn(alg: string, ai: ref Keyring->Authinfo, fd: ref Sys->FD): (ref Sys->FD, string);
+ auth: fn(ai: ref Keyring->Authinfo, keyspec: string, alg: string, dfd: ref Sys->FD): (ref Sys->FD, ref Keyring->Authinfo, string);
+ keyfile: fn(keyspec: string): string;
+ key: fn(keyspec: string): ref Keyring->Authinfo;
+};
diff --git a/module/selectfile.m b/module/selectfile.m
new file mode 100644
index 00000000..9cb400c7
--- /dev/null
+++ b/module/selectfile.m
@@ -0,0 +1,13 @@
+Selectfile: module
+{
+ PATH: con "/dis/lib/selectfile.dis";
+
+ init: fn(): string;
+ filename: fn(ctxt: ref Draw->Context, parent: ref Draw->Image,
+ title: string,
+ pat: list of string,
+ dir: string): string;
+# select: fn(top: ref Tk->Toplevel, w: string,
+# root, dir: string,
+# pats: list of string, action: string): chan of (int, string);
+};
diff --git a/module/sets.m b/module/sets.m
new file mode 100644
index 00000000..aae67150
--- /dev/null
+++ b/module/sets.m
@@ -0,0 +1,34 @@
+Sets: module {
+ A: con 2r1010;
+ B: con 2r1100;
+
+ PATH: con "/dis/lib/sets.dis";
+
+ init: fn();
+ set: fn(): Set;
+ str2set: fn(str: string): Set;
+ bytes2set: fn(d: array of byte): Set;
+ Set: adt {
+ m: int;
+ a: array of int;
+
+ X: fn(s1: self Set, o: int, s2: Set): Set;
+ add: fn(s: self Set, n: int): Set;
+ addlist: fn(s: self Set, ns: list of int): Set;
+ # dellist: fn(s: self Set, ns: list of int): Set;
+ del: fn(s: self Set, n: int): Set;
+ invert: fn(s: self Set): Set;
+
+ eq: fn(s1: self Set, s2: Set): int;
+ holds: fn(s: self Set, n: int): int;
+ isempty: fn(s: self Set): int;
+ msb: fn(s: self Set): int;
+ limit: fn(s: self Set): int;
+
+ str: fn(s: self Set): string;
+ bytes: fn(s: self Set, n: int): array of byte;
+ debugstr: fn(s: self Set): string;
+ };
+ All: con Set(~0, nil);
+ None: con Set(0, nil);
+};
diff --git a/module/sets32.m b/module/sets32.m
new file mode 100644
index 00000000..01b969f1
--- /dev/null
+++ b/module/sets32.m
@@ -0,0 +1,33 @@
+Sets: module {
+ A: con 2r1010;
+ B: con 2r1100;
+
+ PATH: con "/dis/lib/sets32.dis";
+
+ init: fn();
+ set: fn(): Set;
+ str2set: fn(str: string): Set;
+ bytes2set: fn(d: array of byte): Set;
+ Set: adt {
+ s: int;
+
+ X: fn(s1: self Set, o: int, s2: Set): Set;
+ add: fn(s: self Set, n: int): Set;
+ addlist: fn(s: self Set, ns: list of int): Set;
+ # dellist: fn(s: self Set, ns: list of int): Set;
+ del: fn(s: self Set, n: int): Set;
+ invert: fn(s: self Set): Set;
+
+ eq: fn(s1: self Set, s2: Set): int;
+ holds: fn(s: self Set, n: int): int;
+ isempty: fn(s: self Set): int;
+ msb: fn(s: self Set): int;
+ limit: fn(s: self Set): int;
+
+ str: fn(s: self Set): string;
+ bytes: fn(s: self Set, lim: int): array of byte;
+ debugstr: fn(s: self Set): string;
+ };
+ All: con Set(~0);
+ None: con Set(0);
+};
diff --git a/module/sexprs.m b/module/sexprs.m
new file mode 100644
index 00000000..63053d2e
--- /dev/null
+++ b/module/sexprs.m
@@ -0,0 +1,41 @@
+Sexprs: module
+{
+ PATH: con "/dis/lib/sexprs.dis";
+
+ Sexp: adt {
+ pick {
+ String =>
+ s: string;
+ hint: string;
+ Binary =>
+ data: array of byte;
+ hint: string;
+ List =>
+ l: cyclic list of ref Sexp;
+ }
+
+ read: fn[T](b: T): (ref Sexp, string) for {
+ T =>
+ getb: fn(nil: self T): int;
+ ungetb: fn(nil: self T): int;
+ offset: fn(nil: self T): big;
+ };
+ parse: fn(s: string): (ref Sexp, string, string);
+ unpack: fn(a: array of byte): (ref Sexp, array of byte, string);
+ text: fn(e: self ref Sexp): string;
+ packedsize: fn(e: self ref Sexp): int;
+ pack: fn(e: self ref Sexp): array of byte;
+ b64text: fn(e: self ref Sexp): string;
+
+ islist: fn(e: self ref Sexp): int;
+ els: fn(e: self ref Sexp): list of ref Sexp;
+ op: fn(e: self ref Sexp): string;
+ args: fn(e: self ref Sexp): list of ref Sexp;
+ eq: fn(e: self ref Sexp, t: ref Sexp): int;
+ copy: fn(e: self ref Sexp): ref Sexp;
+ asdata: fn(e: self ref Sexp): array of byte;
+ astext: fn(e: self ref Sexp): string;
+ };
+
+ init: fn();
+};
diff --git a/module/sh.m b/module/sh.m
new file mode 100644
index 00000000..46df9ddc
--- /dev/null
+++ b/module/sh.m
@@ -0,0 +1,106 @@
+Command: module
+{
+ PATH: con "/dis/sh.dis";
+
+ init: fn(ctxt: ref Draw->Context, argv: list of string);
+};
+
+Sh: module
+{
+ PATH: con "/dis/sh.dis";
+ initialise: fn();
+ init: fn(ctxt: ref Draw->Context, argv: list of string);
+ system: fn(drawctxt: ref Draw->Context, cmd: string): string;
+ run: fn(drawctxt: ref Draw->Context, argv: list of string): string;
+ parse: fn(s: string): (ref Cmd, string);
+ cmd2string: fn(c: ref Cmd): string;
+
+ Context: adt {
+ new: fn(drawcontext: ref Draw->Context): ref Context;
+ get: fn(c: self ref Context, name: string): list of ref Listnode;
+ set: fn(c: self ref Context, name: string, val: list of ref Listnode);
+ setlocal: fn(c: self ref Context, name: string, val: list of ref Listnode);
+ envlist: fn(c: self ref Context): list of (string, list of ref Listnode);
+ push: fn(c: self ref Context);
+ pop: fn(c: self ref Context);
+ copy: fn(c: self ref Context, copyenv: int): ref Context;
+ run: fn(c: self ref Context, args: list of ref Listnode, last: int): string;
+ addmodule: fn(c: self ref Context, name: string, mod: Shellbuiltin);
+ addbuiltin: fn(c: self ref Context, name: string, mod: Shellbuiltin);
+ removebuiltin: fn(c: self ref Context, name: string, mod: Shellbuiltin);
+ addsbuiltin: fn(c: self ref Context, name: string, mod: Shellbuiltin);
+ removesbuiltin: fn(c: self ref Context, name: string, mod: Shellbuiltin);
+ fail: fn(c: self ref Context, ename, msg: string);
+ options: fn(c: self ref Context): int;
+ setoptions: fn(c: self ref Context, flags, on: int): int;
+ INTERACTIVE, VERBOSE, EXECPRINT, ERROREXIT: con 1 << iota;
+
+ env: ref Environment;
+ waitfd: ref Sys->FD;
+ drawcontext: ref Draw->Context;
+ keepfds: list of int;
+ };
+
+ list2stringlist: fn(nl: list of ref Listnode): list of string;
+ stringlist2list: fn(sl: list of string): list of ref Listnode;
+ quoted: fn(val: list of ref Listnode, quoteblocks: int): string;
+
+ initbuiltin: fn(c: ref Context, sh: Sh): string;
+ whatis: fn(nil: ref Sh->Context, nil: Sh, nil: string, nil: int): string;
+ runbuiltin: fn(c: ref Context, sh: Sh, cmd: list of ref Listnode, last: int): string;
+ runsbuiltin: fn(c: ref Context, sh: Sh, cmd: list of ref Listnode): list of ref Listnode;
+ getself: fn(): Shellbuiltin;
+ Cmd: type Node;
+ Node: adt {
+ ntype: int;
+ left, right: ref Node;
+ word: string;
+ redir: ref Redir;
+ };
+ Redir: adt {
+ rtype: int;
+ fd1, fd2: int;
+ };
+ Var: adt {
+ name: string;
+ val: list of ref Listnode;
+ flags: int;
+ CHANGED, NOEXPORT: con (1 << iota);
+ };
+ Environment: adt {
+ sbuiltins: ref Builtins;
+ builtins: ref Builtins;
+ bmods: list of (string, Shellbuiltin);
+ localenv: ref Localenv;
+ };
+ Localenv: adt {
+ vars: array of list of ref Var;
+ pushed: ref Localenv;
+ flags: int;
+ };
+ Listnode: adt {
+ cmd: ref Node;
+ word: string;
+ };
+ Builtins: adt {
+ ba: array of (string, list of Shellbuiltin);
+ n: int;
+ };
+ # node types
+ n_BLOCK, n_VAR, n_BQ, n_BQ2, n_REDIR,
+ n_DUP, n_LIST, n_SEQ, n_CONCAT, n_PIPE, n_ADJ,
+ n_WORD, n_NOWAIT, n_SQUASH, n_COUNT,
+ n_ASSIGN, n_LOCAL: con iota;
+ GLOB: con 1;
+};
+
+Shellbuiltin: module {
+ initbuiltin: fn(c: ref Sh->Context, sh: Sh): string;
+ runbuiltin: fn(c: ref Sh->Context, sh: Sh,
+ cmd: list of ref Sh->Listnode, last: int): string;
+ runsbuiltin: fn(c: ref Sh->Context, sh: Sh,
+ cmd: list of ref Sh->Listnode): list of ref Sh->Listnode;
+ BUILTIN, SBUILTIN, OTHER: con iota;
+ whatis: fn(c: ref Sh->Context, sh: Sh, name: string, wtype: int): string;
+ getself: fn(): Shellbuiltin;
+};
diff --git a/module/smtp.m b/module/smtp.m
new file mode 100644
index 00000000..b339c1fe
--- /dev/null
+++ b/module/smtp.m
@@ -0,0 +1,22 @@
+# smtp protocol independent access to an email server.
+
+Smtp : module
+{
+ PATH : con "/dis/lib/smtp.dis";
+
+ # all functions return status (-ve when error)
+
+ # open a connection with the email server
+ # requires the email server's name or address or nil if a default server is to be used
+ # returns (status, errror string)
+ open: fn(server : string) : (int, string);
+
+ # send mail - returns (status, error string)
+ sendmail: fn(fromwho: string,
+ towho: list of string,
+ cc : list of string,
+ msg: list of string) : (int, string);
+
+ # close the connection - returns (status, error string)
+ close: fn() : (int, string);
+};
diff --git a/module/sort.m b/module/sort.m
new file mode 100644
index 00000000..9a4828b3
--- /dev/null
+++ b/module/sort.m
@@ -0,0 +1,8 @@
+Sort: module {
+ PATH: con "/dis/lib/sort.dis";
+ sort: fn[S, T](s: S, a: array of T)
+ for{
+ S =>
+ gt: fn(s: self S, x, y: T): int;
+ };
+};
diff --git a/module/spki.m b/module/spki.m
new file mode 100644
index 00000000..bb922a3c
--- /dev/null
+++ b/module/spki.m
@@ -0,0 +1,239 @@
+Rawsexprs: module
+{
+ PATH: con "rawsexprs.dis";
+
+ Sexp: adt {
+ pick {
+ String =>
+ s: string;
+ hint: string;
+ Binary =>
+ data: array of byte;
+ hint: string;
+ List =>
+ l: cyclic list of ref Sexp;
+ }
+
+ unpack: fn(a: array of byte): (ref Sexp, array of byte, string);
+ text: fn(e: self ref Sexp): string;
+ packedsize: fn(e: self ref Sexp): int;
+ pack: fn(e: self ref Sexp): array of byte;
+ };
+
+ init: fn();
+};
+
+SPKI: module
+{
+ PATH: con "/dis/lib/spki/spki.dis";
+
+ Hash: adt {
+ alg: string;
+ hash: array of byte;
+
+ sexp: fn(h: self ref Hash): ref Sexprs->Sexp;
+ text: fn(h: self ref Hash): string;
+ eq: fn(h1: self ref Hash, h2: ref Hash): int;
+ };
+
+ Key: adt {
+ pk: ref Keyring->PK; # either pk/sk or hash might be nil
+ sk: ref Keyring->SK;
+ nbits: int;
+ halg: string;
+ hash: ref Hash;
+
+ hashed: fn(k: self ref Key, alg: string): array of byte;
+ sigalg: fn(k: self ref Key): string;
+ text: fn(k: self ref Key): string;
+ sexp: fn(k: self ref Key): ref Sexprs->Sexp;
+ eq: fn(k1: self ref Key, k2: ref Key): int;
+ };
+
+ Name: adt {
+ principal: ref Key;
+ names: list of string;
+
+ isprincipal: fn(n: self ref Name): int;
+ local: fn(n: self ref Name): ref Name;
+ islocal: fn(n: self ref Name): int;
+ isprefix: fn(n1: self ref Name, n2: ref Name): int;
+ text: fn(n: self ref Name): string;
+ sexp: fn(n: self ref Name): ref Sexprs->Sexp;
+ eq: fn(n1: self ref Name, n2: ref Name): int;
+ };
+
+ Cert: adt {
+ e: ref Sexprs->Sexp; # S-expression, if originally parsed
+ issuer: ref Name;
+ subject: ref Subject;
+ valid: ref Valid;
+ pick {
+ A or KH or O => # auth, keyholder or object
+ delegate: int;
+ tag: ref Sexprs->Sexp;
+ N => # name
+ }
+
+ text: fn(c: self ref Cert): string;
+ sexp: fn(c: self ref Cert): ref Sexprs->Sexp;
+ };
+
+ # the pick might move to a more general `Principal' structure,
+ # allowing compound and quoting principals
+ Subject: adt {
+ pick{
+ P =>
+ key: ref Key;
+ N =>
+ name: ref Name;
+ O =>
+ hash: ref Hash;
+ KH =>
+ holder: ref Name;
+ T =>
+ k, n: int;
+ subs: cyclic list of ref Subject;
+ }
+
+ eq: fn(s1: self ref Subject, s2: ref Subject): int;
+ principal: fn(s: self ref Subject): ref Key;
+ text: fn(s: self ref Subject): string;
+ sexp: fn(s: self ref Subject): ref Sexprs->Sexp;
+ };
+
+ Principal: adt[T] {
+ pick{
+ N =>
+ name: ref Name;
+ Q =>
+ quoter: T;
+ quotes: cyclic ref Principal;
+ }
+ };
+
+ Signature: adt {
+ hash: ref Hash;
+ key: ref Key; # find by hash if necessary
+ sa: string;
+ sig: list of (string, array of byte);
+
+ algs: fn(s: self ref Signature): (string, string, string);
+ sexp: fn(s: self ref Signature): ref Sexprs->Sexp;
+ text: fn(s: self ref Signature): string;
+ };
+
+ Seqel: adt {
+ pick{
+ C =>
+ c: ref Cert;
+ K =>
+ k: ref Key;
+ O =>
+ op: string;
+ args: list of ref Sexprs->Sexp;
+ S =>
+ sig: ref Signature;
+ RV => # <reval>
+ ok: list of (string, string);
+ onetime: array of byte;
+ valid: ref Valid;
+ CRL =>
+ bad: list of (string, string);
+ valid: ref Valid;
+ Delta =>
+ hash: string;
+ bad: list of (string, string);
+ valid: ref Valid;
+ E =>
+ exp: ref Sexprs->Sexp;
+ }
+
+ text: fn(se: self ref Seqel): string;
+ };
+
+ Valid: adt {
+ notbefore: string;
+ notafter: string;
+
+ intersect: fn(a: self Valid, b: Valid): (int, Valid);
+ text: fn(a: self Valid): string;
+ sexp: fn(a: self Valid): ref Sexprs->Sexp;
+ };
+
+ Toplev: adt {
+ pick {
+ C =>
+ v: ref Cert;
+ Sig =>
+ v: ref Signature;
+ K =>
+ v: ref Key;
+ Seq =>
+ v: list of ref Seqel;
+ }
+ };
+
+ init: fn();
+
+ # parse structures
+ parse: fn(s: ref Sexprs->Sexp): (ref Toplev, string);
+ parseseq: fn(s: ref Sexprs->Sexp): list of ref Seqel;
+ parsecert: fn(s: ref Sexprs->Sexp): ref Cert;
+ parsesig: fn(s: ref Sexprs->Sexp): ref Signature;
+ parsename: fn(s: ref Sexprs->Sexp): ref Name;
+ parsekey: fn(s: ref Sexprs->Sexp): ref Key;
+ parsehash: fn(s: ref Sexprs->Sexp): ref Hash;
+ parsecompound: fn(s: ref Sexprs->Sexp): ref Name;
+ parsevalid: fn(s: ref Sexprs->Sexp): ref Valid;
+
+ # signature checking
+ checksig: fn(c: ref Cert, sig: ref Signature): string;
+ sig2icert: fn(sig: ref Signature, signer: string, exp: int): ref Keyring->Certificate;
+
+ # tags
+ maketag: fn(e: ref Sexprs->Sexp): ref Sexprs->Sexp;
+ tagintersect: fn(t1: ref Sexprs->Sexp, t2: ref Sexprs->Sexp): ref Sexprs->Sexp;
+ tagimplies: fn(t1: ref Sexprs->Sexp, t2: ref Sexprs->Sexp): int;
+
+ # hash canonical s-expression
+ hashbytes: fn(a: array of byte, alg: string): array of byte;
+ hashexp: fn(e: ref Sexprs->Sexp, alg: string): array of byte;
+
+ # convert between date and time strings and Inferno form
+ date2epoch: fn(s: string): int; # YYYY-MM-DD_HH:MM:SS
+ epoch2date: fn(t: int): string;
+ time2secs: fn(s: string): int; # HH:MM:SS
+ secs2time: fn(t: int): string;
+
+ # debugging
+ dump: fn(s: string, a: array of byte);
+};
+
+Proofs: module
+{
+ Proof: adt {
+ n: int;
+
+ parse: fn(s: string): ref Proof;
+ sexp: fn(p: self ref Proof): ref Sexprs->Sexp;
+ text: fn(p: self ref Proof): string;
+ };
+
+ init: fn(): string;
+};
+
+Verifier: module
+{
+ PATH: con "/dis/lib/spki/verifier.dis";
+
+ Speaksfor: adt {
+ subject: ref SPKI->Subject;
+ name: ref SPKI->Name;
+ regarding: ref Sexprs->Sexp;
+ valid: ref SPKI->Valid;
+ };
+
+ init: fn();
+ verify: fn(seq: list of ref SPKI->Seqel): (ref Speaksfor, list of ref SPKI->Seqel, string);
+};
diff --git a/module/srv.m b/module/srv.m
new file mode 100644
index 00000000..d87dfd64
--- /dev/null
+++ b/module/srv.m
@@ -0,0 +1,17 @@
+Srv: module
+{
+ PATH: con "$Srv"; # some hosted, never native
+
+ #
+ # IP network database lookups
+ #
+ # iph2a: host name to ip addrs
+ # ipa2h: ip addr to host aliases
+ # ipn2p: service name to port
+ #
+ iph2a: fn(host: string): list of string;
+ ipa2h: fn(addr: string): list of string;
+ ipn2p: fn(net, service: string): string;
+
+ init: fn();
+};
diff --git a/module/srvrunt.b b/module/srvrunt.b
new file mode 100644
index 00000000..60ca6a90
--- /dev/null
+++ b/module/srvrunt.b
@@ -0,0 +1,3 @@
+implement nothing;
+
+include "srv.m";
diff --git a/module/ssl3.m b/module/ssl3.m
new file mode 100644
index 00000000..32c47bd7
--- /dev/null
+++ b/module/ssl3.m
@@ -0,0 +1,204 @@
+#
+# ssl 3.0 protocol
+#
+
+SSL3: module {
+
+ PATH: con "/dis/lib/crypt/ssl3.dis";
+
+ init: fn(): string;
+
+ # SSL cipher suites
+
+ NULL_WITH_NULL_NULL,
+ RSA_WITH_NULL_MD5,
+ RSA_WITH_NULL_SHA,
+ RSA_EXPORT_WITH_RC4_40_MD5,
+ RSA_WITH_RC4_128_MD5,
+ RSA_WITH_RC4_128_SHA,
+ RSA_EXPORT_WITH_RC2_CBC_40_MD5,
+ RSA_WITH_IDEA_CBC_SHA,
+ RSA_EXPORT_WITH_DES40_CBC_SHA,
+ RSA_WITH_DES_CBC_SHA,
+ RSA_WITH_3DES_EDE_CBC_SHA,
+ DH_DSS_EXPORT_WITH_DES40_CBC_SHA,
+ DH_DSS_WITH_DES_CBC_SHA,
+ DH_DSS_WITH_3DES_EDE_CBC_SHA,
+ DH_RSA_EXPORT_WITH_DES40_CBC_SHA,
+ DH_RSA_WITH_DES_CBC_SHA,
+ DH_RSA_WITH_3DES_EDE_CBC_SHA,
+ DHE_DSS_EXPORT_WITH_DES40_CBC_SHA,
+ DHE_DSS_WITH_DES_CBC_SHA,
+ DHE_DSS_WITH_3DES_EDE_CBC_SHA,
+ DHE_RSA_EXPORT_WITH_DES40_CBC_SHA,
+ DHE_RSA_WITH_DES_CBC_SHA,
+ DHE_RSA_WITH_3DES_EDE_CBC_SHA,
+ DH_anon_EXPORT_WITH_RC4_40_MD5,
+ DH_anon_WITH_RC4_128_MD5,
+ DH_anon_EXPORT_WITH_DES40_CBC_SHA,
+ DH_anon_WITH_DES_CBC_SHA,
+ DH_anon_WITH_3DES_EDE_CBC_SHA,
+ FORTEZZA_KEA_WITH_NULL_SHA,
+ FORTEZZA_KEA_WITH_FORTEZZA_CBC_SHA,
+ FORTEZZA_KEA_WITH_RC4_128_SHA : con iota;
+
+ Authinfo: adt {
+ suites: array of byte; # [2] x
+ comprs: array of byte; # [1] x
+
+ sk: ref PrivateKey; # for user certs
+ root_type: int; # root type of certs
+ certs: list of array of byte; # x509 cert chain
+
+ types: array of byte; # acceptable cert types
+ dns: list of array of byte; # acceptable cert authorities
+ };
+
+ PrivateKey: adt {
+ pick {
+ RSA =>
+ sk : ref PKCS->RSAKey;
+ DSS =>
+ sk : ref PKCS->DSSPrivateKey;
+ DH =>
+ sk : ref PKCS->DHPrivateKey;
+ }
+ };
+
+ Record: adt {
+ content_type : int;
+ version : array of byte; # [2]
+ data : array of byte;
+ };
+
+ # key exchange algorithms
+
+ KeyExAlg: adt {
+ pick {
+ NULL =>
+ DH =>
+ params : ref PKCS->DHParams;
+ sk : ref PKCS->DHPrivateKey;
+ peer_params : ref PKCS->DHParams;
+ peer_pk : ref PKCS->DHPublicKey;
+ exch_pk : ref PKCS->DHPublicKey;
+ RSA =>
+ sk : ref PKCS->RSAKey; # for RSA key exchange
+ export_key : ref PKCS->RSAKey; # server RSA temp key
+ peer_pk : ref PKCS->RSAKey; # temp key from server
+ FORTEZZA_KEA =>
+ # not supported yet
+ }
+ };
+
+ SigAlg: adt {
+ pick {
+ anon =>
+ RSA =>
+ sk : ref PKCS->RSAKey; # for sign
+ peer_pk : ref PKCS->RSAKey; # for verify from peer cert
+ DSS =>
+ sk : ref PKCS->DSSPrivateKey; # for sign
+ peer_pk : ref PKCS->DSSPublicKey; # for verify from peer cert
+ FORTEZZA_KEA => # not supported yet
+ }
+ };
+
+ CipherSpec: adt {
+ is_exportable : int;
+
+ bulk_cipher_algorithm : int;
+ cipher_type : int;
+ key_material : int;
+ IV_size : int;
+
+ mac_algorithm : int;
+ hash_size : int;
+ };
+
+ # record format queue
+
+ RecordQueue: adt {
+ macState : ref MacState;
+ cipherState : ref CipherState;
+
+ length : int;
+ sequence_numbers : array of int;
+
+ data : list of ref Record;
+ fragment : int;
+ b, e : int;
+
+ new: fn(): ref RecordQueue;
+ read: fn(q: self ref RecordQueue, ctx: ref Context, fd: ref Sys->FD): string;
+ write: fn(q: self ref RecordQueue, ctx: ref Context, fd: ref Sys->FD, r: ref Record): string;
+ calcmac: fn(q: self ref RecordQueue, ctx: ref Context, cntype: int, a: array of byte, ofs, n: int) : array of byte;
+ };
+
+ MacState: adt {
+ hash_size : int;
+ pick {
+ null =>
+ md5 =>
+ ds : array of ref Keyring->DigestState;
+ sha =>
+ ds : array of ref Keyring->DigestState;
+ }
+ };
+
+ CipherState: adt {
+ block_size : int;
+ pick {
+ null =>
+ rc4 =>
+ es : ref Keyring->RC4state;
+ descbc =>
+ es : ref Keyring->DESstate;
+ ideacbc =>
+ es : ref Keyring->IDEAstate;
+ }
+ };
+
+ # context for processing both v2 and v3 protocols.
+
+ Context: adt {
+ c : ref Sys->Connection;
+ session : ref SSLsession->Session;
+
+ sel_keyx : ref KeyExAlg;
+ sel_sign : ref SigAlg;
+ sel_ciph : ref CipherSpec;
+ sel_cmpr : int;
+
+ local_info : ref Authinfo;
+
+ client_random : array of byte; # [32]
+ server_random : array of byte; # [32]
+
+ sha_state : ref Keyring->DigestState;
+ md5_state : ref Keyring->DigestState;
+
+ cw_mac : array of byte;
+ sw_mac : array of byte;
+ cw_key : array of byte;
+ sw_key : array of byte;
+ cw_IV : array of byte;
+ sw_IV : array of byte;
+
+ in_queue : ref RecordQueue;
+ out_queue : ref RecordQueue;
+
+ status : int;
+ state : int;
+
+
+ new: fn(): ref Context;
+ client: fn(ctx: self ref Context, fd: ref Sys->FD, peer: string, ver: int, info: ref Authinfo): (string, int);
+ server: fn(ctx: self ref Context, fd: ref Sys->FD, info: ref Authinfo, client_auth: int): string;
+ use_devssl: fn(ctx: self ref Context);
+ set_version: fn(ctx: self ref Context, vers: int): string;
+ connect: fn(ctx: self ref Context, fd: ref Sys->FD): string;
+ read: fn(ctx: self ref Context, a: array of byte, n: int): int;
+ write: fn(ctx: self ref Context, a: array of byte, n: int): int;
+ };
+};
diff --git a/module/sslsession.m b/module/sslsession.m
new file mode 100644
index 00000000..6afa3110
--- /dev/null
+++ b/module/sslsession.m
@@ -0,0 +1,27 @@
+SSLsession: module {
+
+ PATH: con "/dis/lib/crypt/sslsession.dis";
+
+ Session: adt {
+ session_id : array of byte; # [32]
+ peer : string;
+
+ connection_time : int;
+ version : array of byte; # [2]
+
+ suite : array of byte; # [2]
+ compression : byte;
+
+ master_secret : array of byte; # [48]
+ peer_certs : list of array of byte;
+
+ new: fn(peer: string, time: int, ver: array of byte): ref Session;
+ duplicate: fn(s: self ref Session): ref Session;
+ };
+
+ init: fn(): string;
+ add_session: fn(s: ref Session);
+ get_session_byid: fn(session_id: array of byte): ref Session;
+ get_session_byname: fn(peer: string): ref Session;
+ set_timeout: fn(t: int);
+};
diff --git a/module/string.m b/module/string.m
new file mode 100644
index 00000000..41ce5e4e
--- /dev/null
+++ b/module/string.m
@@ -0,0 +1,39 @@
+String: module
+{
+ PATH: con "/dis/lib/string.dis";
+
+ # the second arg of the following is a character class
+ # e.g., "a-zA-Z", or "^ \t\n"
+ # (ranges indicated by - except in first position;
+ # ^ is first position means "not in" the following class)
+ # splitl splits just before first char in class; (s, "") if no split
+ # splitr splits just after last char in class; ("", s) if no split
+ # drop removes maximal prefix in class
+ # take returns maximal prefix in class
+
+ splitl: fn(s, cl: string): (string, string);
+ splitr: fn(s, cl: string): (string, string);
+ drop: fn(s, cl: string): string;
+ take: fn(s, cl: string): string;
+ in: fn(c: int, cl: string): int;
+
+ # in these, the second string is a string to match, not a class
+ splitstrl: fn(s, t: string): (string, string);
+ splitstrr: fn(s, t: string): (string, string);
+
+ # is first arg a prefix of second?
+ prefix: fn(pre, s: string): int;
+
+ tolower: fn(s: string): string;
+ toupper: fn(s: string): string;
+
+ # string to int returning value, remainder
+ toint: fn(s: string, base: int): (int, string);
+ tobig: fn(s: string, base: int): (big, string);
+
+ # append s to end of l
+ append: fn(s: string, l: list of string): list of string;
+ quoted: fn(argv: list of string): string;
+ quotedc: fn(argv: list of string, cl: string): string;
+ unquoted: fn(args: string): list of string;
+};
diff --git a/module/strinttab.m b/module/strinttab.m
new file mode 100644
index 00000000..936dcb3b
--- /dev/null
+++ b/module/strinttab.m
@@ -0,0 +1,17 @@
+StringIntTab: module
+{
+ PATH: con "/dis/lib/strinttab.dis";
+
+ StringInt: adt{
+ key: string;
+ val: int;
+ };
+
+ # Binary search of t (which must be sorted) for key.
+ # Returns (found, val).
+ lookup: fn(t: array of StringInt, key: string) : (int, int);
+
+ # Linear search of t for first pair with given val.
+ # Returns key (nil if no match).
+ revlookup: fn(t: array of StringInt, val: int) : string;
+};
diff --git a/module/strokes.m b/module/strokes.m
new file mode 100644
index 00000000..fd062745
--- /dev/null
+++ b/module/strokes.m
@@ -0,0 +1,122 @@
+#
+# Li-Yeung character recognition
+#
+Strokes: module
+{
+ PATH: con "/dis/lib/strokes/strokes.dis";
+
+ Penpoint: adt
+ {
+ x, y: int;
+ chaincode: int;
+ };
+
+ Stroke: adt
+ {
+ npts: int;
+ pts: array of Penpoint;
+ xrange, yrange: int;
+
+ new: fn(n: int): ref Stroke;
+ copy: fn(nil: self ref Stroke): ref Stroke;
+ trim: fn(nil: self ref Stroke, n: int);
+ bbox: fn(nil: self ref Stroke): (int, int, int, int);
+ scaleup: fn(nil: self ref Stroke): int;
+ translate: fn(nil: self ref Stroke, minx: int, miny: int, scalex: int, scaley: int);
+ center: fn(nil: self ref Stroke);
+ regions: fn(nil: self ref Stroke): ref Region;
+ dominant: fn(nil: self ref Stroke): ref Stroke;
+ interpolate: fn(points: self ref Stroke): ref Stroke;
+ length: fn(nil: self ref Stroke): int;
+ pathlen: fn(nil: self ref Stroke, first: int, last: int): int;
+ contourangles: fn(nil: self ref Stroke, regions: ref Region): array of int;
+ filter: fn(nil: self ref Stroke): ref Stroke;
+ };
+
+ # ordered list of regions
+ Region: adt
+ {
+ rtype: int;
+ start: int;
+ end: int;
+ next: cyclic ref Region;
+ };
+
+ # region types
+ Rconvex, Rconcave, Rplain, Rpseudo: con iota;
+
+ Classifier: adt
+ {
+ nclasses: int; # number of symbols in class
+ examples: array of list of ref Stroke; # optional training examples
+ cnames: array of string; # the class names
+ canonex: array of ref Stroke; # optional canonical versions of the strokes
+ dompts: array of ref Stroke; # dominant points
+
+ match: fn(nil: self ref Classifier, stroke: ref Stroke): (int, string);
+ };
+
+ init: fn();
+
+ preprocess_stroke: fn(nil: ref Stroke);
+ score_stroke: fn(a: ref Stroke, b: ref Stroke): (int, int);
+
+ compute_similarity: fn(a: ref Stroke, b: ref Stroke): int;
+ compute_distance: fn(a: ref Stroke, b: ref Stroke): int;
+ compute_chain_code: fn(nil: ref Stroke);
+ compute_unit_chain_code: fn(pts: ref Stroke);
+
+ regiontype: fn(ang: int): int;
+
+ sqrt: fn(n: int): int;
+ likeatan: fn(top: int, bot: int): int;
+ quadr: fn(t: int): int;
+
+ printpoints: fn(fd: ref Sys->FD, nil: ref Stroke, sep: string);
+
+ MAXDIST: con 16r7FFFFFFF;
+};
+
+Readstrokes: module
+{
+ PATH: con "/dis/lib/strokes/readstrokes.dis";
+
+ init: fn(nil: Strokes);
+ read_classifier: fn(file: string, build: int, needex: int): (string, ref Strokes->Classifier);
+ read_digest: fn(fd: ref Sys->FD): (string, array of string, array of ref Strokes->Stroke);
+ read_examples: fn(fd: ref Sys->FD): (string, array of string, array of list of ref Strokes->Stroke);
+};
+
+Writestrokes: module
+{
+ PATH: con "/dis/lib/strokes/writestrokes.dis";
+
+ init: fn(nil: Strokes);
+ write_digest: fn(fd: ref Sys->FD, nil: array of string, nil: array of ref Strokes->Stroke): string;
+ write_examples: fn(fd: ref Sys->FD, nil: array of string, nil: array of list of ref Strokes->Stroke): string;
+};
+
+Buildstrokes: module
+{
+ PATH: con "/dis/lib/strokes/buildstrokes.dis";
+
+ init: fn(nil: Strokes);
+ canonical_example: fn(n: int, cnames: array of string, nil: array of list of ref Strokes->Stroke): (string, array of ref Strokes->Stroke, array of ref Strokes->Stroke);
+ canonical_stroke: fn(points: ref Strokes->Stroke): ref Strokes->Stroke;
+ compute_equipoints: fn(nil: ref Strokes->Stroke): ref Strokes->Stroke;
+};
+
+# special characters and gestures
+# in digits.cl: BNASRPUVWX
+# in punc.cl: TFGHIJK
+# in letters.cl: ABNPRSUVWX
+
+# L caps lock
+# N num lock
+# P ctrl (Unix), punc shift (orig)
+# S shift
+
+# A space
+# B backspace
+# R return
+# . puncshift
diff --git a/module/styx.m b/module/styx.m
new file mode 100644
index 00000000..aee41599
--- /dev/null
+++ b/module/styx.m
@@ -0,0 +1,182 @@
+Styx: module
+{
+ PATH: con "/dis/lib/styx.dis";
+ PATHV1: con "/dis/lib/styx1.dis";
+
+ VERSION: con "9P2000";
+ MAXWELEM: con 16;
+
+ NOTAG: con 16rFFFF;
+ NOFID: con int ~0; # 32 bits in this version of Styx
+
+ BIT8SZ: con 1;
+ BIT16SZ: con 2;
+ BIT32SZ: con 4;
+ BIT64SZ: con 8;
+ QIDSZ: con BIT8SZ+BIT32SZ+BIT64SZ;
+
+ STATFIXLEN: con BIT16SZ+QIDSZ+5*BIT16SZ+4*BIT32SZ+BIT64SZ; # amount of fixed length data in a stat buffer
+ IOHDRSZ: con 24; # room for Twrite/Rread header
+ MAXFDATA: con 8192; # `reasonable' iounit
+ MAXRPC: con IOHDRSZ+MAXFDATA; # usable default for fversion and iounit
+
+ Tversion, # 100
+ Rversion,
+ Tauth, # 102
+ Rauth,
+ Tattach, # 104
+ Rattach,
+ Terror, # 106, illegal
+ Rerror,
+ Tflush, #108
+ Rflush,
+ Twalk, # 110
+ Rwalk,
+ Topen, # 112
+ Ropen,
+ Tcreate, # 114
+ Rcreate,
+ Tread, # 116
+ Rread,
+ Twrite, # 118
+ Rwrite,
+ Tclunk, # 120
+ Rclunk,
+ Tremove, # 122
+ Rremove,
+ Tstat, # 124
+ Rstat,
+ Twstat, #126
+ Rwstat,
+ Tmax: con 100+iota;
+
+ ERRMAX: con 128;
+
+ OREAD: con 0; # open for read
+ OWRITE: con 1; # write
+ ORDWR: con 2; # read and write
+ OEXEC: con 3; # execute, == read but check execute permission
+ OTRUNC: con 16; # or'ed in (except for exec), truncate file first
+ ORCLOSE: con 64; # or'ed in, remove on close
+
+ # mode bits in Dir.mode used by the protocol
+ DMDIR: con int 1<<31; # mode bit for directory
+ DMAPPEND: con int 1<<30; # mode bit for append-only files
+ DMEXCL: con int 1<<29; # mode bit for exclusive use files
+ DMAUTH: con int 1<<27; # mode bit for authentication files
+
+ # Qid.qtype
+ QTDIR: con 16r80;
+ QTAPPEND: con 16r40;
+ QTEXCL: con 16r20;
+ QTAUTH: con 16r08;
+ QTFILE: con 16r00;
+
+ Tmsg: adt {
+ tag: int;
+ pick {
+ Readerror =>
+ error: string; # tag is unused in this case
+ Version =>
+ msize: int;
+ version: string;
+ Auth =>
+ afid: int;
+ uname, aname: string;
+ Attach =>
+ fid, afid: int;
+ uname, aname: string;
+ Flush =>
+ oldtag: int;
+ Walk =>
+ fid, newfid: int;
+ names: array of string;
+ Open =>
+ fid, mode: int;
+ Create =>
+ fid: int;
+ name: string;
+ perm, mode: int;
+ Read =>
+ fid: int;
+ offset: big;
+ count: int;
+ Write =>
+ fid: int;
+ offset: big;
+ data: array of byte;
+ Clunk or
+ Stat or
+ Remove =>
+ fid: int;
+ Wstat =>
+ fid: int;
+ stat: Sys->Dir;
+ }
+
+ read: fn(fd: ref Sys->FD, msize: int): ref Tmsg;
+ unpack: fn(a: array of byte): (int, ref Tmsg);
+ pack: fn(nil: self ref Tmsg): array of byte;
+ packedsize: fn(nil: self ref Tmsg): int;
+ text: fn(nil: self ref Tmsg): string;
+ mtype: fn(nil: self ref Tmsg): int;
+ };
+
+ Rmsg: adt {
+ tag: int;
+ pick {
+ Readerror =>
+ error: string; # tag is unused in this case
+ Version =>
+ msize: int;
+ version: string;
+ Auth =>
+ aqid: Sys->Qid;
+ Attach =>
+ qid: Sys->Qid;
+ Flush =>
+ Error =>
+ ename: string;
+ Clunk or
+ Remove or
+ Wstat =>
+ Walk =>
+ qids: array of Sys->Qid;
+ Create or
+ Open =>
+ qid: Sys->Qid;
+ iounit: int;
+ Read =>
+ data: array of byte;
+ Write =>
+ count: int;
+ Stat =>
+ stat: Sys->Dir;
+ }
+
+ read: fn(fd: ref Sys->FD, msize: int): ref Rmsg;
+ unpack: fn(a: array of byte): (int, ref Rmsg);
+ pack: fn(nil: self ref Rmsg): array of byte;
+ packedsize: fn(nil: self ref Rmsg): int;
+ text: fn(nil: self ref Rmsg): string;
+ mtype: fn(nil: self ref Rmsg): int;
+ };
+
+ init: fn();
+
+ readmsg: fn(fd: ref Sys->FD, msize: int): (array of byte, string);
+ istmsg: fn(f: array of byte): int;
+
+ compatible: fn(t: ref Tmsg.Version, msize: int, version: string): (int, string);
+
+ packdirsize: fn(d: Sys->Dir): int;
+ packdir: fn(d: Sys->Dir): array of byte;
+ unpackdir: fn(f: array of byte): (int, Sys->Dir);
+ dir2text: fn(d: Sys->Dir): string;
+ qid2text: fn(q: Sys->Qid): string;
+
+ utflen: fn(s: string): int;
+
+ # temporary undocumented compatibility function
+ write: fn(fd: ref Sys->FD, a: array of byte, n: int): int;
+};
diff --git a/module/styxconv.m b/module/styxconv.m
new file mode 100644
index 00000000..2752d3c6
--- /dev/null
+++ b/module/styxconv.m
@@ -0,0 +1,9 @@
+Styxconv: module
+{
+ PATH: con "/dis/lib/styxconv/styxconv.dis";
+
+ # call first
+ init: fn();
+ # spawn and synchronize
+ styxconv: fn(in: ref Sys->FD, out: ref Sys->FD, sync: chan of int);
+};
diff --git a/module/styxlib.m b/module/styxlib.m
new file mode 100644
index 00000000..7564f3f3
--- /dev/null
+++ b/module/styxlib.m
@@ -0,0 +1,87 @@
+#
+# deprecated: use styxservers(2) instead
+#
+
+Styxlib: module
+{
+ PATH: con "/dis/lib/styxlib.dis";
+ Chan: adt {
+ fid: int;
+ qid: Sys->Qid;
+ open: int;
+ mode: int;
+ uname: string;
+ path: string;
+ data: array of byte;
+
+ isdir: fn(c: self ref Chan): int;
+ };
+
+ Dirtab: adt {
+ name: string;
+ qid: Sys->Qid;
+ length: big;
+ perm: int;
+ };
+
+ Styxserver: adt {
+ fd: ref Sys->FD;
+ chans: array of list of ref Chan;
+ uname: string;
+ msize: int;
+
+ new: fn(fd: ref Sys->FD): (chan of ref Styx->Tmsg, ref Styxserver);
+ reply: fn(srv: self ref Styxserver, m: ref Styx->Rmsg): int;
+
+ fidtochan: fn(srv: self ref Styxserver, fid: int): ref Chan;
+ newchan: fn(srv: self ref Styxserver, fid: int): ref Chan;
+ chanfree: fn(srv: self ref Styxserver, c: ref Chan);
+ chanlist: fn(srv: self ref Styxserver): list of ref Chan;
+ clone: fn(srv: self ref Styxserver, c: ref Chan, fid: int): ref Chan;
+
+ devversion: fn(srv: self ref Styxserver, m: ref Styx->Tmsg.Version): int;
+ devauth: fn(srv: self ref Styxserver, m: ref Styx->Tmsg.Auth);
+ devattach: fn(srv: self ref Styxserver, m: ref Styx->Tmsg.Attach): ref Chan;
+ devflush: fn(srv: self ref Styxserver, m: ref Styx->Tmsg.Flush);
+ devwalk: fn(srv: self ref Styxserver, m: ref Styx->Tmsg.Walk,
+ gen: Dirgenmod, tab: array of Dirtab): ref Chan;
+ devclunk: fn(srv: self ref Styxserver, m: ref Styx->Tmsg.Clunk): ref Chan;
+ devstat: fn(srv: self ref Styxserver, m: ref Styx->Tmsg.Stat,
+ gen: Dirgenmod, tab: array of Dirtab);
+ devdirread: fn(srv: self ref Styxserver, m: ref Styx->Tmsg.Read,
+ gen: Dirgenmod, tab: array of Dirtab);
+ devopen: fn(srv: self ref Styxserver, m: ref Styx->Tmsg.Open,
+ gen: Dirgenmod, tab: array of Dirtab): ref Chan;
+ devremove: fn(srv: self ref Styxserver, m: ref Styx->Tmsg.Remove): ref Chan;
+ };
+
+ init: fn(s: Styx): string;
+
+ readbytes: fn(m: ref Styx->Tmsg.Read, d: array of byte): ref Styx->Rmsg.Read;
+ readnum: fn(m: ref Styx->Tmsg.Read, val, size: int): ref Styx->Rmsg.Read;
+ readstr: fn(m: ref Styx->Tmsg.Read, d: string): ref Styx->Rmsg.Read;
+
+ openok: fn(omode, perm: int, uname, funame, fgname: string): int;
+ openmode: fn(o: int): int;
+
+ devdir: fn(c: ref Chan, qid: Sys->Qid, n: string, length: big,
+ user: string, perm: int): Sys->Dir;
+
+ dirgenmodule: fn(): Dirgenmod;
+ dirgen: fn(srv: ref Styxserver, c: ref Chan, tab: array of Dirtab, i: int): (int, Sys->Dir);
+
+ Einuse : con "fid already in use";
+ Ebadfid : con "bad fid";
+ Eopen : con "fid already opened";
+ Enotfound : con "file does not exist";
+ Enotdir : con "not a directory";
+ Eperm : con "permission denied";
+ Ebadarg : con "bad argument";
+ Eexists : con "file already exists";
+};
+
+
+Dirgenmod: module {
+ dirgen: fn(srv: ref Styxlib->Styxserver, c: ref Styxlib->Chan,
+ tab: array of Styxlib->Dirtab, i: int): (int, Sys->Dir);
+};
diff --git a/module/styxpersist.m b/module/styxpersist.m
new file mode 100644
index 00000000..118fc774
--- /dev/null
+++ b/module/styxpersist.m
@@ -0,0 +1,4 @@
+Styxpersist: module {
+ PATH: con "/dis/lib/styxpersist.dis";
+ init: fn(clientfd: ref Sys->FD, usefac: int, keyspec: string): (chan of chan of ref Sys->FD, string);
+};
diff --git a/module/styxservers.m b/module/styxservers.m
new file mode 100644
index 00000000..b9b47cf7
--- /dev/null
+++ b/module/styxservers.m
@@ -0,0 +1,135 @@
+Styxservers: module
+{
+ PATH: con "/dis/lib/styxservers.dis";
+
+ Fid: adt {
+ fid: int; # client's fid
+ path: big; # file's 64-bit unique path
+ qtype: int; # file's qid type (eg, Sys->QTDIR if directory)
+ isopen: int; # non-zero if file is open
+ mode: int; # if open, the open mode
+ doffset: (int, int); # (internal) cache of directory offset
+ uname: string; # user name from original attach
+ param: string; # attach aname from original attach
+ data: array of byte; # application data
+
+ clone: fn(f: self ref Fid, nf: ref Fid): ref Fid;
+ open: fn(f: self ref Fid, mode: int, qid: Sys->Qid);
+ walk: fn(f: self ref Fid, qid: Sys->Qid);
+ };
+
+ Navigator: adt {
+ c: chan of ref Navop;
+ reply: chan of (ref Sys->Dir, string);
+
+ new: fn(c: chan of ref Navop): ref Navigator;
+ stat: fn(t: self ref Navigator, q: big): (ref Sys->Dir, string);
+ walk: fn(t: self ref Navigator, parentq: big, name: string): (ref Sys->Dir, string);
+ readdir: fn(t: self ref Navigator, q: big, offset, count: int): array of ref Sys->Dir;
+ };
+
+ Navop: adt {
+ reply: chan of (ref Sys->Dir, string); # channel for reply
+ path: big; # file or directory path
+ pick {
+ Stat =>
+ Walk =>
+ name: string;
+ Readdir =>
+ offset: int; # index (origin 0) of first directory entry to return
+ count: int; # number of directory entries requested
+ }
+ };
+
+ Styxserver: adt {
+ fd: ref Sys->FD; # file server end of connection
+ fids: array of list of ref Fid; # hash table of fids
+ fidlock: chan of int;
+ t: ref Navigator; # name space navigator for this server
+ rootpath: big; # Qid.path of root of its name space
+ msize: int; # negotiated Styx message size
+ replychan: chan of ref Styx->Rmsg;
+
+ new: fn(fd: ref Sys->FD, t: ref Navigator, rootpath: big): (chan of ref Styx->Tmsg, ref Styxserver);
+ reply: fn(srv: self ref Styxserver, m: ref Styx->Rmsg): int;
+ replydirect: fn(srv: self ref Styxserver, m: ref Styx->Rmsg): int;
+
+ # protocol operations
+ attach: fn(srv: self ref Styxserver, m: ref Styx->Tmsg.Attach): ref Fid;
+ clunk: fn(srv: self ref Styxserver, m: ref Styx->Tmsg.Clunk): ref Fid;
+ walk: fn(srv: self ref Styxserver, m: ref Styx->Tmsg.Walk): ref Fid;
+ open: fn(srv: self ref Styxserver, m: ref Styx->Tmsg.Open): ref Fid;
+ read: fn(srv: self ref Styxserver, m: ref Styx->Tmsg.Read): ref Fid;
+ remove: fn(srv: self ref Styxserver, m: ref Styx->Tmsg.Remove): ref Fid;
+ stat: fn(srv: self ref Styxserver, m: ref Styx->Tmsg.Stat);
+
+ default: fn(srv: self ref Styxserver, gm: ref Styx->Tmsg);
+
+ # check validity but don't reply
+ cancreate: fn(srv: self ref Styxserver, m: ref Styx->Tmsg.Create): (ref Fid, int, ref Sys->Dir, string);
+ canopen: fn(srv: self ref Styxserver, m: ref Styx->Tmsg.Open): (ref Fid, int, ref Sys->Dir, string);
+ canremove: fn(srv: self ref Styxserver, m: ref Styx->Tmsg.Remove): (ref Fid, big, string);
+ canread: fn(srv: self ref Styxserver, m: ref Styx->Tmsg.Read): (ref Fid, string);
+ canwrite: fn(srv: self ref Styxserver, m: ref Styx->Tmsg.Write): (ref Fid, string);
+
+ # fid management
+ getfid: fn(srv: self ref Styxserver, fid: int): ref Fid;
+ newfid: fn(srv: self ref Styxserver, fid: int): ref Fid;
+ delfid: fn(srv: self ref Styxserver, c: ref Fid);
+ allfids: fn(srv: self ref Styxserver): list of ref Fid;
+
+ iounit: fn(srv: self ref Styxserver): int;
+ };
+
+ init: fn(styx: Styx);
+ traceset: fn(on: int);
+
+ readbytes: fn(m: ref Styx->Tmsg.Read, d: array of byte): ref Styx->Rmsg.Read;
+ readstr: fn(m: ref Styx->Tmsg.Read, s: string): ref Styx->Rmsg.Read;
+
+ openok: fn(uname: string, omode, perm: int, fuid, fgid: string): int;
+ openmode: fn(o: int): int;
+
+ Einuse: con "fid already in use";
+ Ebadfid: con "bad fid";
+ Eopen: con "fid already opened";
+ Enotfound: con "file does not exist";
+ Enotdir: con "not a directory";
+ Eperm: con "permission denied";
+ Ebadarg: con "bad argument";
+ Eexists: con "file already exists";
+ Emode: con "open/create -- unknown mode";
+ Eoffset: con "read/write -- bad offset";
+ Ecount: con "read/write -- count negative or exceeds msgsize";
+ Enotopen: con "read/write -- on non open fid";
+ Eaccess: con "read/write -- not open in suitable mode";
+ Ename: con "bad character in file name";
+ Edot: con ". and .. are illegal names";
+};
+
+Nametree: module {
+ PATH: con "/dis/lib/nametree.dis";
+ Tree: adt {
+ c: chan of ref Treeop;
+ reply: chan of string;
+
+ quit: fn(t: self ref Tree);
+ create: fn(t: self ref Tree, parent: big, d: Sys->Dir): string;
+ wstat: fn(t: self ref Tree, path: big, d: Sys->Dir): string;
+ remove: fn(t: self ref Tree, path: big): string;
+ getpath: fn(t: self ref Tree, path: big): string;
+ };
+ Treeop: adt {
+ reply: chan of string;
+ q: big;
+ pick {
+ Create or
+ Wstat =>
+ d: Sys->Dir;
+ Remove =>
+ Getpath =>
+ }
+ };
+ init: fn();
+ start: fn(): (ref Tree, chan of ref Styxservers->Navop);
+};
diff --git a/module/sys.m b/module/sys.m
new file mode 100644
index 00000000..1fed789f
--- /dev/null
+++ b/module/sys.m
@@ -0,0 +1,160 @@
+
+SELF: con "$self"; # Language support for loading my instance
+
+Sys: module
+{
+ PATH: con "$Sys";
+
+ Maxint: con 2147483647;
+
+ # Unique file identifier for file objects
+ Qid: adt
+ {
+ path: big;
+ vers: int;
+ qtype: int;
+ };
+
+ QTDIR: con 16r80;
+ QTAPPEND: con 16r40;
+ QTEXCL: con 16r20;
+ QTAUTH: con 16r08;
+ QTTMP: con 16r04;
+ QTFILE: con 0;
+
+ # Return from stat and directory read
+ Dir: adt
+ {
+ name: string;
+ uid: string;
+ gid: string;
+ muid: string;
+ qid: Qid;
+ mode: int;
+ atime: int;
+ mtime: int;
+ length: big;
+ dtype: int;
+ dev: int;
+ };
+ nulldir: con Dir(nil, nil, nil, nil, (~big 0, ~0, ~0), ~0, ~0, ~0, ~big 0, ~0, ~0);
+ zerodir: con Dir(nil, nil, nil, nil, (big 0, 0, 0), 0, 0, 0, big 0, 0, 0);
+
+ # File descriptor
+ #
+ FD: adt
+ {
+ fd: int;
+ };
+
+ # Network connection returned by dial
+ #
+ Connection: adt
+ {
+ dfd: ref FD;
+ cfd: ref FD;
+ dir: string;
+ };
+
+ # File IO structures returned from file2chan
+ # read: (offset, bytes, fid, chan)
+ # write: (offset, data, fid, chan)
+ #
+ Rread: type chan of (array of byte, string);
+ Rwrite: type chan of (int, string);
+ FileIO: adt
+ {
+ read: chan of (int, int, int, Rread);
+ write: chan of (int, array of byte, int, Rwrite);
+ };
+
+ # Maximum read which will be completed atomically;
+ # also the optimum block size
+ #
+ ATOMICIO: con 8192;
+
+ SEEKSTART: con 0;
+ SEEKRELA: con 1;
+ SEEKEND: con 2;
+
+ NAMEMAX: con 256;
+ ERRMAX: con 128;
+ WAITLEN: con ERRMAX+64;
+
+ OREAD: con 0;
+ OWRITE: con 1;
+ ORDWR: con 2;
+ OTRUNC: con 16;
+ ORCLOSE: con 64;
+ OEXCL: con 16r1000;
+
+ DMDIR: con int 1<<31;
+ DMAPPEND: con int 1<<30;
+ DMEXCL: con int 1<<29;
+ DMAUTH: con int 1<<27;
+ DMTMP: con int 1<<26;
+
+ MREPL: con 0;
+ MBEFORE: con 1;
+ MAFTER: con 2;
+ MCREATE: con 4;
+ MCACHE: con 16;
+
+ NEWFD: con (1<<0);
+ FORKFD: con (1<<1);
+ NEWNS: con (1<<2);
+ FORKNS: con (1<<3);
+ NEWPGRP: con (1<<4);
+ NODEVS: con (1<<5);
+ NEWENV: con (1<<6);
+ FORKENV: con (1<<7);
+
+ EXPWAIT: con 0;
+ EXPASYNC: con 1;
+
+ UTFmax: con 3;
+ UTFerror: con 16r80;
+
+ announce: fn(addr: string): (int, Connection);
+ aprint: fn(s: string, *): array of byte;
+ bind: fn(s, on: string, flags: int): int;
+ byte2char: fn(buf: array of byte, n: int): (int, int, int);
+ char2byte: fn(c: int, buf: array of byte, n: int): int;
+ chdir: fn(path: string): int;
+ create: fn(s: string, mode, perm: int): ref FD;
+ dial: fn(addr, local: string): (int, Connection);
+ dirread: fn(fd: ref FD): (int, array of Dir);
+ dup: fn(old, new: int): int;
+ export: fn(c: ref FD, dir: string, flag: int): int;
+ fauth: fn(fd: ref FD, aname: string): ref FD;
+ fd2path: fn(fd: ref FD): string;
+ fildes: fn(fd: int): ref FD;
+ file2chan: fn(dir, file: string): ref FileIO;
+ fprint: fn(fd: ref FD, s: string, *): int;
+ fstat: fn(fd: ref FD): (int, Dir);
+ fversion: fn(fd: ref FD, msize: int, version: string): (int, string);
+ fwstat: fn(fd: ref FD, d: Dir): int;
+ iounit: fn(fd: ref FD): int;
+ listen: fn(c: Connection): (int, Connection);
+ millisec: fn(): int;
+ mount: fn(fd: ref FD, afd: ref FD, on: string, flags: int, spec: string): int;
+ open: fn(s: string, mode: int): ref FD;
+ pctl: fn(flags: int, movefd: list of int): int;
+ pipe: fn(fds: array of ref FD): int;
+ print: fn(s: string, *): int;
+ pread: fn(fd: ref FD, buf: array of byte, n: int, off: big): int;
+ pwrite: fn(fd: ref FD, buf: array of byte, n: int, off: big): int;
+ read: fn(fd: ref FD, buf: array of byte, n: int): int;
+ remove: fn(s: string): int;
+ seek: fn(fd: ref FD, off: big, start: int): big;
+ sleep: fn(period: int): int;
+ sprint: fn(s: string, *): string;
+ stat: fn(s: string): (int, Dir);
+ stream: fn(src, dst: ref FD, bufsiz: int): int;
+ tokenize: fn(s, delim: string): (int, list of string);
+ unmount: fn(s1: string, s2: string): int;
+ utfbytes: fn(buf: array of byte, n: int): int;
+ werrstr: fn(s: string): int;
+ write: fn(fd: ref FD, buf: array of byte, n: int): int;
+ wstat: fn(s: string, d: Dir): int;
+};
diff --git a/module/tables.m b/module/tables.m
new file mode 100644
index 00000000..62f589a8
--- /dev/null
+++ b/module/tables.m
@@ -0,0 +1,24 @@
+Tables: module {
+ PATH: con "/dis/lib/tables.dis";
+ Table: adt[T] {
+ items: array of list of (int, T);
+ nilval: T;
+
+ new: fn(nslots: int, nilval: T): ref Table[T];
+ add: fn(t: self ref Table, id: int, x: T): int;
+ del: fn(t: self ref Table, id: int): int;
+ find: fn(t: self ref Table, id: int): T;
+ };
+
+ Strhash: adt[T] {
+ items: array of list of (string, T);
+ nilval: T;
+
+ new: fn(nslots: int, nilval: T): ref Strhash[T];
+ add: fn(t: self ref Strhash, id: string, x: T);
+ del: fn(t: self ref Strhash, id: string);
+ find: fn(t: self ref Strhash, id: string): T;
+ };
+
+ hash: fn(s: string, n: int): int;
+};
diff --git a/module/tabs.m b/module/tabs.m
new file mode 100644
index 00000000..c1b66fe1
--- /dev/null
+++ b/module/tabs.m
@@ -0,0 +1,16 @@
+Tabs: module
+{
+ PATH: con "/dis/lib/tabs.dis";
+
+ init: fn();
+
+ mktabs: fn(t: ref Tk->Toplevel, dot: string,
+ tabs: array of (string, string),
+ dflt: int): chan of string;
+
+ tabsctl: fn(t: ref Tk->Toplevel,
+ dot: string,
+ tabs: array of (string, string),
+ id: int,
+ s: string): int;
+};
diff --git a/module/tcllib.m b/module/tcllib.m
new file mode 100644
index 00000000..39222c62
--- /dev/null
+++ b/module/tcllib.m
@@ -0,0 +1,6 @@
+TclLib : module
+{
+ exec : fn(tcl : ref Tcl_Core->TclData,argv : array of string) :
+ (int,string);
+ about : fn() : array of string;
+};
diff --git a/module/tftp.m b/module/tftp.m
new file mode 100644
index 00000000..af8778ff
--- /dev/null
+++ b/module/tftp.m
@@ -0,0 +1,6 @@
+Tftp: module
+{
+ PATH: con "/dis/lib/tftp.dis";
+ init: fn(progress: int);
+ receive: fn(host: string, filename: string, fd: ref Sys->FD): string;
+};
diff --git a/module/timers.m b/module/timers.m
new file mode 100644
index 00000000..4d2cdb58
--- /dev/null
+++ b/module/timers.m
@@ -0,0 +1,17 @@
+Timers: module
+{
+ PATH: con "/dis/lib/timers.dis";
+
+ Sec: con 1000;
+
+ Timer: adt {
+ dt: int;
+ timeout: chan of int;
+
+ start: fn(msec: int): ref Timer;
+ stop: fn(t: self ref Timer);
+ };
+
+ init: fn(gran: int): int;
+ shutdown: fn();
+};
diff --git a/module/titlebar.m b/module/titlebar.m
new file mode 100644
index 00000000..10dd0800
--- /dev/null
+++ b/module/titlebar.m
@@ -0,0 +1,18 @@
+Titlebar: module{
+ PATH: con "/dis/lib/titlebar.dis";
+
+ Resize,
+ Hide,
+ Help,
+ OK,
+ Popup,
+ Plain: con 1 << iota;
+ Appl: con Resize | Hide;
+
+ init: fn();
+ new: fn(top: ref Tk->Toplevel, buts: int): chan of string;
+ minsize: fn(top: ref Tk->Toplevel): Draw->Point;
+ title: fn(top: ref Tk->Toplevel): string;
+ settitle: fn(top: ref Tk->Toplevel, title: string): string;
+ sendctl: fn(top: ref Tk->Toplevel, c: string);
+};
diff --git a/module/tk.m b/module/tk.m
new file mode 100644
index 00000000..d54fee83
--- /dev/null
+++ b/module/tk.m
@@ -0,0 +1,25 @@
+Tk: module
+{
+ PATH: con "$Tk";
+
+ Toplevel: adt
+ {
+ display: ref Draw->Display;
+ wreq: chan of string;
+ image: ref Draw->Image;
+ ctxt: ref Draw->Wmcontext; # placeholder, not used by tk
+ screenr: Draw->Rect; # writable
+ };
+ Border, Required, Local: con 1<<iota;
+ rect: fn(t: ref Toplevel, name: string, flags: int): Draw->Rect;
+
+ toplevel: fn(d: ref Draw->Display, arg: string): ref Toplevel;
+ namechan: fn(t: ref Toplevel, c: chan of string, n: string): string;
+ cmd: fn(t: ref Toplevel, arg: string): string;
+ pointer: fn(t: ref Toplevel, p: Draw->Pointer);
+ keyboard: fn(t: ref Toplevel, key: int);
+ putimage: fn(t: ref Toplevel, name: string, i, m: ref Draw->Image): string;
+ getimage: fn(t: ref Toplevel, name: string): (ref Draw->Image, ref Draw->Image, string);
+ quote: fn(s: string): string;
+ color: fn(col: string): int;
+};
diff --git a/module/tkclient.m b/module/tkclient.m
new file mode 100644
index 00000000..7a4d3b14
--- /dev/null
+++ b/module/tkclient.m
@@ -0,0 +1,26 @@
+Tkclient: module
+{
+ PATH: con "/dis/lib/tkclient.dis";
+
+ Resize,
+ Hide,
+ Help,
+ OK,
+ Popup, # XXX is this useful?
+ Plain: con 1 << iota;
+
+ Appl: con Resize | Hide;
+
+ init: fn();
+ makedrawcontext: fn(): ref Draw->Context;
+ toplevel: fn(ctxt: ref Draw->Context, topconfig: string,
+ title: string, buts: int): (ref Tk->Toplevel, chan of string);
+ onscreen: fn(top: ref Tk->Toplevel, how: string);
+ startinput: fn(top: ref Tk->Toplevel, devs: list of string);
+ wmctl: fn(top: ref Tk->Toplevel, request: string): string;
+ settitle: fn(top: ref Tk->Toplevel, name: string): string;
+ handler: fn(top: ref Tk->Toplevel, stop: chan of int);
+
+ snarfput: fn(buf: string);
+ snarfget: fn(): string;
+};
diff --git a/module/translate.m b/module/translate.m
new file mode 100644
index 00000000..786fb8ee
--- /dev/null
+++ b/module/translate.m
@@ -0,0 +1,30 @@
+#
+# Copyright © 2000 Vita Nuova Limited
+#
+Translate: module
+{
+ PATH: con "/dis/lib/translate.dis";
+
+ Dict: adt {
+ texts: array of list of ref Phrase;
+ notes: array of list of ref Phrase;
+
+ new: fn(): ref Dict;
+ add: fn(d: self ref Dict, file: string): string;
+ xlate: fn(d: self ref Dict, nil: string): string;
+ xlaten: fn(d: self ref Dict, nil: string, note: string): string;
+ };
+
+ Phrase: adt {
+ key: string;
+ text: string; # nil for a note
+ hash: int;
+ n: int;
+ note: int;
+ };
+
+ init: fn();
+ opendict: fn(file: string): (ref Dict, string);
+ opendicts: fn(files: list of string): (ref Dict, string);
+ mkdictname: fn(locale, app: string): string;
+};
diff --git a/module/ubfa.m b/module/ubfa.m
new file mode 100644
index 00000000..981742fa
--- /dev/null
+++ b/module/ubfa.m
@@ -0,0 +1,57 @@
+UBFa: module
+{
+ PATH: con "/dis/lib/ubfa.dis";
+
+ UValue: adt {
+ pick{
+ Atom =>
+ name: string;
+ Int =>
+ value: int; # should have big as well?
+ String =>
+ s: string;
+ Binary =>
+ a: array of byte;
+ Tuple =>
+ a: cyclic array of ref UValue; # tree
+ List =>
+ l: cyclic list of ref UValue; # tree
+ Tag =>
+ name: string;
+ o: cyclic ref UValue;
+ }
+
+ isatom: fn(o: self ref UValue): int;
+ isstring: fn(o: self ref UValue): int;
+ isint: fn(o: self ref UValue): int;
+ istuple: fn(o: self ref UValue): int;
+ isop: fn(o: self ref UValue, op: string, arity: int): int;
+ islist: fn(o: self ref UValue): int;
+ isbinary: fn(o: self ref UValue): int;
+ istag: fn(o: self ref UValue): int;
+ text: fn(o: self ref UValue): string;
+ eq: fn(o: self ref UValue, v: ref UValue): int;
+ op: fn(o: self ref UValue, arity: int): string;
+ args: fn(o: self ref UValue, arity: int): array of ref UValue;
+ els: fn(o: self ref UValue): list of ref UValue;
+ val: fn(o: self ref UValue): int;
+ binary: fn(o: self ref UValue): array of byte;
+ objtag: fn(o: self ref UValue): string;
+ obj: fn(o: self ref UValue): ref UValue;
+ };
+
+ init: fn(bufio: Bufio);
+ readubf: fn(input: ref Iobuf): (ref UValue, string);
+ writeubf: fn(out: ref Iobuf, obj: ref UValue): int;
+ uniq: fn(s: string): string;
+
+ # shorthand
+ uvatom: fn(s: string): ref UValue.Atom;
+ uvint: fn(i: int): ref UValue.Int;
+ uvbig: fn(i: big): ref UValue.Int;
+ uvstring: fn(s: string): ref UValue.String;
+ uvbinary: fn(a: array of byte): ref UValue.Binary;
+ uvtuple: fn(a: array of ref UValue): ref UValue.Tuple;
+ uvlist: fn(l: list of ref UValue): ref UValue.List;
+ uvtag: fn(name: string, o: ref UValue): ref UValue.Tag;
+};
diff --git a/module/unbundle.m b/module/unbundle.m
new file mode 100644
index 00000000..89e78230
--- /dev/null
+++ b/module/unbundle.m
@@ -0,0 +1,9 @@
+Unbundle: module {
+ PATH: con "/dis/fs/bundle.dis";
+
+ types: fn(): string;
+ init: fn();
+ run: fn(nil: ref Draw->Context, report: ref Report,
+ nil: list of Option, args: list of ref Value): ref Value;
+ unbundle: fn(r: ref Fslib->Report, iob: ref Bufio->Iobuf, seekable: int, blocksize: int): Fslib->Fschan;
+};
diff --git a/module/url.m b/module/url.m
new file mode 100644
index 00000000..fa537076
--- /dev/null
+++ b/module/url.m
@@ -0,0 +1,34 @@
+Url: module
+{
+ PATH : con "/dis/lib/url.dis";
+
+ # scheme ids
+ NOSCHEME, HTTP, HTTPS, FTP, FILE, GOPHER, MAILTO, NEWS,
+ NNTP, TELNET, WAIS, PROSPERO, JAVASCRIPT, UNKNOWN: con iota;
+
+ # general url syntax:
+ # <scheme>://<user>:<passwd>@<host>:<port>/<path>?<query>#<fragment>
+ #
+ # relative urls might omit some prefix of the above
+ ParsedUrl: adt
+ {
+ scheme: int;
+ utf8: int; # strings not in us-ascii
+ user: string;
+ passwd: string;
+ host: string;
+ port: string;
+ pstart: string; # what precedes <path>: either "/" or ""
+ path: string;
+ query: string;
+ frag: string;
+
+ makeabsolute: fn(url: self ref ParsedUrl, base: ref ParsedUrl);
+ tostring: fn(url: self ref ParsedUrl) : string;
+ };
+
+ schemes: array of string;
+
+ init: fn(); # call before anything else
+ makeurl: fn(s: string) : ref ParsedUrl;
+};
diff --git a/module/usb.m b/module/usb.m
new file mode 100644
index 00000000..ccd31550
--- /dev/null
+++ b/module/usb.m
@@ -0,0 +1,130 @@
+Usb: module
+{
+ PATH: con "/dis/lib/usb/usb.dis";
+ DATABASEPATH: con "/lib/usbdb";
+ RH2D: con 0<<7;
+ RD2H: con 1<<7;
+ Rstandard: con 0<<5;
+ Rclass: con 1<<5;
+ Rvendor: con 2<<5;
+ Rdevice: con 0;
+ Rinterface: con 1;
+ Rendpt: con 2;
+ Rother: con 3;
+
+ GET_STATUS: con 0;
+ CLEAR_FEATURE: con 1;
+ SET_FEATURE: con 3;
+ SET_ADDRESS: con 5;
+ GET_DESCRIPTOR: con 6;
+ SET_DESCRIPTOR: con 7;
+ GET_CONFIGURATION: con 8;
+ SET_CONFIGURATION: con 9;
+ GET_INTERFACE: con 10;
+ SET_INTERFACE: con 11;
+ SYNCH_FRAME: con 12;
+
+ DEVICE: con 1;
+ CONFIGURATION: con 2;
+ STRING: con 3;
+ INTERFACE: con 4;
+ ENDPOINT: con 5;
+ HID: con 16r21;
+ REPORT: con 16r22;
+ PHYSICAL: con 16r23;
+ HUB: con 16r29;
+
+ CL_AUDIO: con 1;
+ CL_COMMS: con 2;
+ CL_HID: con 3;
+ CL_PRINTER: con 7;
+ CL_MASS: con 8;
+ CL_HUB: con 9;
+ CL_DATA: con 10;
+
+ DDEVLEN: con 18;
+ DCONFLEN: con 9;
+ DINTERLEN: con 9;
+ DENDPLEN: con 7;
+ DHUBLEN: con 9;
+ DHIDLEN: con 9;
+
+ PORT_CONNECTION: con 0;
+ PORT_ENABLE: con 1;
+ PORT_SUSPEND: con 2;
+ PORT_OVER_CURRENT: con 3;
+ PORT_RESET: con 4;
+ PORT_POWER: con 8;
+ PORT_LOW_SPEED: con 9;
+
+ Endpt: adt {
+ addr: int;
+ d2h: int;
+ attr: int;
+ etype: int;
+ isotype: int;
+ maxpkt: int;
+ interval: int;
+ };
+
+ Econtrol, Eiso, Ebulk, Eintr: con iota; # Endpt.etype
+ Eunknown, Easync, Eadapt, Esync: con iota; # Endpt.isotype
+
+ NendPt: con 16;
+
+ Device: adt {
+ usbmajor, usbminor, relmajor, relminor: int;
+ class, subclass, proto, maxpkt0, vid, did, nconf: int;
+ };
+
+ AltInterface: adt {
+ id: int;
+ class, subclass, proto: int;
+ ep: array of ref Endpt;
+ };
+
+ Interface: adt {
+ altiface: list of ref AltInterface;
+ };
+
+ Configuration: adt {
+ id: int;
+ attr: int;
+ powerma: int;
+ iface: array of Interface;
+ };
+
+ init: fn();
+ get2: fn(b: array of byte): int;
+ put2: fn(buf: array of byte, v: int);
+ get4: fn(b: array of byte): int;
+ put4: fn(buf: array of byte, v: int);
+ bigget2: fn(b: array of byte): int;
+ bigput2: fn(buf: array of byte, v: int);
+ bigget4: fn(b: array of byte): int;
+ bigput4: fn(buf: array of byte, v: int);
+ memset: fn(b: array of byte, v: int);
+ strtol: fn(s: string, base: int): (int, string);
+ sclass: fn(class, subclass, proto: int): string;
+
+ get_descriptor: fn(fd: ref Sys->FD, rtyp: int, dtyp: int, dindex: int, langid: int, buf: array of byte): int;
+ get_standard_descriptor: fn(fd: ref Sys->FD, dtyp: int, index: int, buf: array of byte): int;
+ get_class_descriptor: fn(fd: ref Sys->FD, dtyp: int, index: int, buf: array of byte): int;
+ get_vendor_descriptor: fn(fd: ref Sys->FD, dtyp: int, index: int, buf: array of byte): int;
+ get_status: fn(fd: ref Sys->FD, port: int): int;
+ set_address: fn(fd: ref Sys->FD, address: int): int;
+ set_configuration: fn(fd: ref Sys->FD, n: int): int;
+ setclear_feature: fn(fd: ref Sys->FD, rtyp: int, value: int, index: int, on: int): int;
+ setup: fn(setupfd: ref Sys->FD, typ, req, value, index: int, outbuf: array of byte, inbuf: array of byte): int;
+ get_parsed_configuration_descriptor: fn(fd: ref Sys->FD, n: int): ref Configuration;
+ get_parsed_device_descriptor: fn(fd: ref Sys->FD): ref Device;
+
+ dump_configuration: fn(fd: ref Sys->FD, conf: ref Configuration);
+};
+
+UsbDriver: module
+{
+ MOUSEPATH: con "/appl/cmd/usb/usbmouse.dis";
+ init: fn(usb: Usb, setupfd, ctlfd: ref Sys->FD, dev: ref Usb->Device, conf: array of ref Usb->Configuration, path: string): int;
+ shutdown: fn();
+};
diff --git a/module/venti.m b/module/venti.m
new file mode 100644
index 00000000..021d436c
--- /dev/null
+++ b/module/venti.m
@@ -0,0 +1,159 @@
+Venti: module {
+ PATH: con "/dis/lib/venti.dis";
+ Scoresize: con 20;
+ Maxstringsize: con 1000;
+ Authsize: con 1024; # size of auth group - in bits - must be multiple of 8
+ Maxfragsize: con 9*1024;
+
+ Cryptostrengthnone,
+ Cryptostrengthauth,
+ Cryptostrengthweak,
+ Cryptostrengthstrong: con iota;
+
+ Cryptonone,
+ CryptoSSL3,
+ CryptoTLS1,
+ Cryptomax: con iota;
+
+ Codecnone,
+ Codecdeflate,
+ CodecThwack,
+ Codecmax: con iota;
+
+ Terror, # not used
+ Rerror,
+ Tping,
+ Rping,
+ Thello,
+ Rhello,
+ Tgoodbye,
+ Rgoodbye, # not used
+ Tauth0,
+ Rauth0,
+ Tauth1,
+ Rauth1,
+ Tread,
+ Rread,
+ Twrite,
+ Rwrite,
+ Tsync,
+ Rsync,
+ Tmax: con iota;
+
+ # versions
+ Version01,
+ Version02: con iota + 1;
+
+ # Lump Types
+ Errtype, # illegal
+
+ Roottype,
+ Dirtype,
+ Pointertype0,
+ Pointertype1,
+ Pointertype2,
+ Pointertype3,
+ Pointertype4,
+ Pointertype5,
+ Pointertype6,
+ Pointertype7, # not used
+ Pointertype8, # not used
+ Pointertype9, # not used
+ Datatype,
+
+ Maxtype: con iota;
+
+ # Dir Entry flags
+ Entryactive: con (1<<0); # entry is in use
+ Entrydir: con (1<<1); # a directory
+ Entrydepthshift: con 2; # shift for pointer depth
+ Entrydepthmask: con (16r7<<2); # mask for pointer depth
+ Entrylocal: con (1<<5); # used for local storage: should not be set for venti blocks
+
+ Maxlumpsize: con 56 * 1024;
+ Pointerdepth: con 7;
+ Entrysize: con 40;
+ Rootsize: con 300;
+ Rootversion: con 2;
+
+ Maxfilesize: con (big 1 << 48) - big 1;
+
+ Vmsg: adt {
+ istmsg: int;
+ tid: int;
+ pick {
+ Thello =>
+ version: string;
+ uid: string;
+ cryptostrength: int;
+ cryptos: array of byte;
+ codecs: array of byte;
+ Rhello =>
+ sid: string;
+ crypto: int;
+ codec: int;
+ Tping =>
+ Rping =>
+ Tread =>
+ score: Score;
+ etype: int;
+ n: int;
+ Rread =>
+ data: array of byte;
+ Twrite =>
+ etype: int;
+ data: array of byte;
+ Rwrite =>
+ score: Score;
+ Tsync =>
+ Rsync =>
+ Tgoodbye =>
+ Rerror =>
+ e: string;
+ }
+ read: fn(fd: ref Sys->FD): (ref Vmsg, string);
+ unpack: fn(a: array of byte): (int, ref Vmsg);
+ pack: fn(nil: self ref Vmsg): array of byte;
+ packedsize: fn(nil: self ref Vmsg): int;
+ text: fn(nil: self ref Vmsg): string;
+ };
+
+ Root: adt {
+ version: int;
+ name: string;
+ rtype: string;
+ score: Venti->Score; # to a Dir block
+ blocksize: int; # maximum block size
+ prev: Venti->Score; # last root block
+ };
+
+ Entry: adt {
+ gen: int; # generation number (XXX should be unsigned)
+ psize: int; # pointer block size
+ dsize: int; # data block size
+ depth: int; # unpacked from flags
+ flags: int;
+ size: big; # (XXX should be unsigned)
+ score: Venti->Score;
+ };
+ Score: adt {
+ a: array of byte;
+ eq: fn(a: self Score, b: Score): int;
+ text: fn(a: self Score): string;
+ parse: fn(s: string): (int, Score);
+ zero: fn(): Score;
+ };
+ Session: adt {
+ fd: ref Sys->FD;
+ version: string;
+
+ new: fn(fd: ref Sys->FD): ref Session;
+ read: fn(s: self ref Session, score: Venti->Score, etype: int, maxn: int): array of byte;
+ write: fn(s: self ref Session, etype: int, buf: array of byte): (int, Venti->Score);
+ sync: fn(s: self ref Session): int;
+ rpc: fn(s: self ref Session, m: ref Vmsg): (ref Vmsg, string);
+ };
+ unpackentry: fn(d: array of byte): ref Entry;
+ unpackroot: fn(d: array of byte): ref Root;
+ init: fn();
+};
diff --git a/module/volume.m b/module/volume.m
new file mode 100644
index 00000000..7ac075c8
--- /dev/null
+++ b/module/volume.m
@@ -0,0 +1,18 @@
+Volumectl: module
+{
+ PATH: con "/dis/lib/volume.dis";
+
+ # Volumectl should be spawned as a separate process from
+ # any process that desires volume control. The parameters
+ # are a ref Context that provides volumectl with access to
+ # the display, a chan of int through which volumectl receives
+ # Ir->Enter, Ir->VolUP, or Ir->VolDN commands (others are
+ # ignored), and a string that names the specific volume to
+ # be controlled (typically "audio out").
+ # Volumectl exits upon receiving Ir->Enter.
+ # It displays a volume control slider when receiving either
+ # Ir->VolUP or Ir->VolDN. The slider automatically disappears
+ # after a period of inactivity.
+
+ volumectl: fn(ctxt: ref Draw->Context, ch: chan of int, device: string);
+};
diff --git a/module/wait.m b/module/wait.m
new file mode 100644
index 00000000..710c481e
--- /dev/null
+++ b/module/wait.m
@@ -0,0 +1,9 @@
+Wait: module
+{
+ PATH: con "/dis/lib/wait.dis";
+
+ init: fn();
+ read: fn(fd: ref Sys->FD): (int, string, string);
+ monitor: fn(fd: ref Sys->FD): (int, chan of (int, string, string));
+ parse: fn(status: string): (int, string, string);
+};
diff --git a/module/watchvars.m b/module/watchvars.m
new file mode 100644
index 00000000..1b80e6be
--- /dev/null
+++ b/module/watchvars.m
@@ -0,0 +1,13 @@
+Watchvars: module {
+ PATH: con "/dis/lib/watchvars.dis";
+ Watchvar: adt[T] {
+ c: chan of (T, chan of T);
+
+ new: fn(v: T): Watchvar[T];
+ get: fn(e: self Watchvar[T]): T;
+ set: fn(e: self Watchvar[T], v: T);
+ wait: fn(e: self Watchvar[T]): T;
+ waitc: fn(e: self Watchvar[T]): (T, chan of T);
+ waited: fn(e: self Watchvar[T], ic: chan of T, v: T);
+ };
+};
diff --git a/module/webget.m b/module/webget.m
new file mode 100644
index 00000000..ca88057e
--- /dev/null
+++ b/module/webget.m
@@ -0,0 +1,7 @@
+Webget: module
+{
+ PATH: con "/dis/svc/webget/webget.dis";
+
+ init: fn(ctxt: ref Draw->Context, argv: list of string);
+ start: fn(ctl: chan of int);
+};
diff --git a/module/winplace.m b/module/winplace.m
new file mode 100644
index 00000000..33b2367b
--- /dev/null
+++ b/module/winplace.m
@@ -0,0 +1,6 @@
+Winplace: module {
+ PATH: con "/dis/lib/winplace.dis";
+ init: fn();
+ place: fn(wins: list of Draw->Rect, scr, lastrect: Draw->Rect, minsize: Draw->Point): Draw->Rect;
+ find: fn(wins: list of Draw->Rect, scr: Draw->Rect): list of Draw->Rect;
+};
diff --git a/module/wmclient.m b/module/wmclient.m
new file mode 100644
index 00000000..cc6f6058
--- /dev/null
+++ b/module/wmclient.m
@@ -0,0 +1,49 @@
+Wmclient: module
+{
+ PATH: con "/dis/lib/wmclient.dis";
+
+ Resize,
+ Hide,
+ Help,
+ OK,
+ Popup,
+ Plain: con 1 << iota;
+ Appl: con Resize | Hide;
+
+ init: fn();
+ makedrawcontext: fn(): ref Draw->Context;
+ window: fn(ctxt: ref Draw->Context, title: string, buts: int): ref Window;
+ snarfput: fn(buf: string);
+ snarfget: fn(): string;
+ cursorspec: fn(img: ref Draw->Image): string;
+
+ Window: adt{
+ display: ref Draw->Display;
+ r: Draw->Rect; # full rectangle of window, including titlebar.
+ image: ref Draw->Image;
+ displayr: Draw->Rect;
+ ctxt: ref Draw->Wmcontext;
+ bd: int;
+ focused: int;
+ ctl: chan of string;
+
+ # private from here:
+ titlebar: ref Tk->Toplevel; # XXX i wish this didn't have to be visible to the application...
+ tbsize: Draw->Point; # size requested by titlebar.
+ tbrect: Draw->Rect;
+ screen: ref Draw->Screen;
+ buttons: int;
+ ptrfocus: int;
+ saved: Draw->Point; # saved origin before task
+
+ startinput: fn(w: self ref Window, devs: list of string);
+ wmctl: fn(w: self ref Window, request: string): string;
+ settitle: fn(w: self ref Window, name: string): string;
+ reshape: fn(w: self ref Window, r: Draw->Rect);
+ onscreen: fn(w: self ref Window, how: string);
+ screenr: fn(w: self ref Window, sr: Draw->Rect): Draw->Rect;
+ imager: fn(w: self ref Window, ir: Draw->Rect): Draw->Rect;
+ pointer: fn(w: self ref Window, p: Draw->Pointer): int;
+ };
+
+};
diff --git a/module/wmlib.m b/module/wmlib.m
new file mode 100644
index 00000000..e46b0506
--- /dev/null
+++ b/module/wmlib.m
@@ -0,0 +1,21 @@
+Wmlib: module
+{
+ PATH: con "/dis/lib/wmlib.dis";
+
+ init: fn();
+ makedrawcontext: fn(): ref Draw->Context;
+ importdrawcontext: fn(devdraw, mntwm: string): (ref Draw->Context, string);
+ connect: fn(ctxt: ref Draw->Context): ref Draw->Wmcontext;
+ reshape: fn(w: ref Draw->Wmcontext, name: string, r: Draw->Rect, i: ref Draw->Image, how: string): ref Draw->Image;
+ startinput: fn(w: ref Draw->Wmcontext, devs: list of string): string; # could be part of connect?
+ wmctl: fn(w: ref Draw->Wmcontext, request: string): (string, ref Draw->Image, string);
+# wmtoken: fn(w: ref Draw->Wmcontext): string;
+ snarfput: fn(buf: string);
+ snarfget: fn(): string;
+
+ # XXX these don't really belong here, but where should they go?
+ splitqword: fn(s: string, e: int): ((int, int), int);
+ qslice: fn(s: string, r: (int, int)): string;
+ qword: fn(s: string, e: int): (string, int);
+ s2r: fn(s: string, e: int): (Draw->Rect, int);
+};
diff --git a/module/wmsrv.m b/module/wmsrv.m
new file mode 100644
index 00000000..d1b82621
--- /dev/null
+++ b/module/wmsrv.m
@@ -0,0 +1,46 @@
+Wmsrv: module{
+ PATH: con "/dis/lib/wmsrv.dis";
+
+ init: fn(): (chan of (string, chan of (string, ref Draw->Wmcontext)),
+ chan of (ref Client, chan of string),
+ chan of (ref Client, array of byte, Sys->Rwrite));
+
+ find: fn(p: Draw->Point): ref Client;
+ top: fn(): ref Client;
+
+ Window: adt {
+ tag: string;
+ r: Rect;
+ img: ref Draw->Image;
+ };
+
+ Client: adt {
+ kbd: chan of int;
+ ptr: chan of ref Draw->Pointer;
+ ctl: chan of string;
+ stop: chan of int;
+ flags: int; # general purpose.
+ cursor: string; # hack.
+ wins: list of ref Window;
+ znext: cyclic ref Client;
+
+ # private:
+ images: chan of (ref Draw->Point, ref Draw->Image, chan of int);
+ id: int; # index into clients array
+ fid: int;
+ token: int;
+ wmctxt: ref Draw->Wmcontext;
+
+ window: fn(c: self ref Client, tag: string): ref Window;
+ contains: fn(c: self ref Client, p: Draw->Point): int;
+ image: fn(c: self ref Client, tag: string): ref Draw->Image;
+ setimage: fn(c: self ref Client, tag: string, i: ref Draw->Image): int; # only in response to some msgs.
+ setorigin: fn(c: self ref Client, tag: string, o: Draw->Point): int; # only in response to some msgs.
+ top: fn(c: self ref Client); # bring to top.
+ bottom: fn(c: self ref Client); # send to bottom.
+ hide: fn(w: self ref Client); # move offscreen.
+ unhide: fn(w: self ref Client); # move onscreen.
+ remove: fn(w: self ref Client);
+ };
+};
+
diff --git a/module/workdir.m b/module/workdir.m
new file mode 100644
index 00000000..3ca7b915
--- /dev/null
+++ b/module/workdir.m
@@ -0,0 +1,8 @@
+Workdir: module
+{
+ PATH: con "/dis/lib/workdir.dis";
+
+ # Return current working directory
+
+ init: fn(): string;
+};
diff --git a/module/x509.m b/module/x509.m
new file mode 100644
index 00000000..3dbec330
--- /dev/null
+++ b/module/x509.m
@@ -0,0 +1,370 @@
+#
+# X.509 v3 by ITU-T Recommendation (11/93) & PKCS7 & PKCS10
+#
+
+X509: module {
+
+ PATH: con "/dis/lib/crypt/x509.dis";
+
+ init: fn(): string;
+
+ ## x509 (id_at) and x509 extention v3 (id_ce) Object Identifiers
+
+ objIdTab : array of ASN1->Oid;
+
+ id_at,
+ id_at_commonName,
+ id_at_countryName,
+ id_at_localityName,
+ id_at_stateOrProvinceName,
+ id_at_organizationName,
+ id_at_organizationalUnitName,
+ id_at_userPassword,
+ id_at_userCertificate,
+ id_at_cAcertificate,
+ id_at_authorityRevocationList,
+ id_at_certificateRevocationList,
+ id_at_crossCertificatePair,
+ id_at_supportedAlgorithms,
+ id_at_deltaRevocationList,
+ id_ce,
+ id_ce_subjectDirectoryAttributes,
+ id_ce_subjectKeyIdentifier,
+ id_ce_keyUsage,
+ id_ce_privateKeyUsage,
+ id_ce_subjectAltName,
+ id_ce_issuerAltName,
+ id_ce_basicConstraints,
+ id_ce_cRLNumber,
+ id_ce_reasonCode,
+ id_ce_instructionCode,
+ id_ce_invalidityDate,
+ id_ce_deltaCRLIndicator,
+ id_ce_issuingDistributionPoint,
+ id_ce_certificateIssuer,
+ id_ce_nameConstraints,
+ id_ce_cRLDistributionPoint,
+ id_ce_certificatePolicies,
+ id_ce_policyMapping,
+ id_ce_authorityKeyIdentifier,
+ id_ce_policyConstraints,
+ id_mr,
+ id_mr_certificateExactMatch,
+ id_mr_certificateMatch,
+ id_mr_certificatePairExactMatch,
+ id_mr_certificatePairMatch,
+ id_mr_certificateListExactMatch,
+ id_mr_certificateListMatch,
+ id_mr_algorithmidentifierMatch : con iota;
+
+ ## Signed (as Public Key, CRL, Attribute Certificates and CertificationRequest)
+
+ Signed: adt {
+ tobe_signed : array of byte;
+ alg : ref AlgIdentifier;
+ signature : array of byte; # BIT STRING, DER encoding
+
+ decode: fn(a: array of byte): (string, ref Signed);
+ encode: fn(s: self ref Signed): (string, array of byte);
+ sign: fn(s: self ref Signed, sk: ref PrivateKey, hash: int): (string, array of byte);
+ verify: fn(s: self ref Signed, pk: ref PublicKey, hash: int): int;
+ tostring: fn(s: self ref Signed): string;
+ };
+
+ ## Certificate Path
+
+ verify_certchain: fn(cs: list of array of byte): (int, string);
+ verify_certpath: fn(cp: list of (ref Signed, ref Certificate)): (int, string);
+
+ ## TBS (Public Key) Certificate
+
+ Certificate: adt {
+ version : int; # v1(0; default) or v2(1) or v3(2)
+ serial_number : ref Keyring->IPint;
+ sig : ref AlgIdentifier;
+ issuer : ref Name;
+ validity : ref Validity;
+ subject : ref Name;
+ subject_pkinfo : ref SubjectPKInfo;
+ # OPTIONAL for v2 and v3; must be in order
+ issuer_uid : array of byte; # v2
+ subject_uid : array of byte; # v2 or v3
+ exts : list of ref Extension; # v3
+
+ decode: fn(a: array of byte): (string, ref Certificate);
+ encode: fn(c: self ref Certificate): (string, array of byte);
+ tostring: fn(c: self ref Certificate): string;
+ is_expired: fn(c: self ref Certificate, date: int): int;
+ };
+
+ AlgIdentifier: adt {
+ oid : ref ASN1->Oid;
+ parameter : array of byte;
+
+ tostring: fn(a: self ref AlgIdentifier): string;
+ };
+
+ Name: adt {
+ rd_names : list of ref RDName;
+
+ equal: fn(a: self ref Name, b: ref Name): int;
+ tostring: fn(n: self ref Name): string;
+ };
+
+ RDName: adt {
+ avas : list of ref AVA;
+
+ equal: fn(a: self ref RDName, b: ref RDName): int;
+ tostring: fn(r: self ref RDName): string;
+ };
+
+ AVA: adt {
+ oid : ref ASN1->Oid;
+ value : string;
+
+ equal: fn(a: self ref AVA, b: ref AVA): int;
+ tostring: fn(a: self ref AVA): string;
+ };
+
+ Validity: adt {
+ not_before : int;
+ not_after : int;
+
+ tostring: fn(v: self ref Validity, format: string): string;
+ };
+
+ SubjectPKInfo: adt {
+ alg_id : ref AlgIdentifier;
+ subject_pk : array of byte; # BIT STRING
+
+ getPublicKey: fn(c: self ref SubjectPKInfo): (string, int, ref PublicKey);
+ tostring: fn(c: self ref SubjectPKInfo): string;
+ };
+
+ Extension: adt{
+ oid : ref ASN1->Oid;
+ critical : int; # default false
+ value : array of byte;
+
+ tostring: fn(e: self ref Extension): string;
+ };
+
+ PublicKey: adt {
+ pick {
+ RSA =>
+ pk : ref PKCS->RSAKey;
+ DSS =>
+ pk : ref PKCS->DSSPublicKey;
+ DH =>
+ pk : ref PKCS->DHPublicKey;
+ }
+ };
+
+ PrivateKey: adt {
+ pick {
+ RSA =>
+ sk : ref PKCS->RSAKey;
+ DSS =>
+ sk : ref PKCS->DSSPrivateKey;
+ DH =>
+ sk : ref PKCS->DHPrivateKey;
+ }
+ };
+
+ ## Certificate Revocation List
+
+ CRL: adt {
+ version : int; # OPTIONAL; v2
+ sig : ref AlgIdentifier;
+ issuer : ref Name;
+ this_update : int;
+ next_update : int; # OPTIONAL
+ revoked_certs : list of ref RevokedCert; # OPTIONAL
+ exts : list of ref Extension; # OPTIONAL
+
+ decode: fn(a: array of byte): (string, ref CRL);
+ encode: fn(c: self ref CRL): (string, array of byte);
+ tostring: fn(c: self ref CRL): string;
+ is_revoked: fn(c: self ref CRL, sn: ref Keyring->IPint): int;
+ };
+
+ RevokedCert: adt {
+ user_cert : ref Keyring->IPint; # serial_number
+ revoc_date : int; # OPTIONAL
+ exts : list of ref Extension; # OPTIONAL; CRL entry extensions
+
+ tostring: fn(rc: self ref RevokedCert): string;
+ };
+
+ ## Certificate Extensions
+
+ # get critical extensions
+ cr_exts: fn(es: list of ref Extension): list of ref Extension;
+
+ # get non-critical extensions
+ noncr_exts: fn(es: list of ref Extension): list of ref Extension;
+
+ # decode a list of extensions
+ parse_exts: fn(es: list of ref Extension): (string, list of ref ExtClass);
+
+ # extension classes
+ ExtClass: adt {
+ pick {
+ AuthorityKeyIdentifier =>
+ id : array of byte; # OCTET STRING
+ issuer : ref GeneralName;
+ serial_number : ref Keyring->IPint;
+ SubjectKeyIdentifier =>
+ id : array of byte; # OCTET STRING
+ BasicConstraints =>
+ depth : int; # certificate path constraints
+ KeyUsage =>
+ usage : int;
+ PrivateKeyUsage =>
+ period : ref Validity;
+ PolicyMapping => # (issuer, subject) domain policy pairs
+ pairs : list of (ref ASN1->Oid, ref ASN1->Oid);
+ CertificatePolicies =>
+ policies : list of ref PolicyInfo;
+ IssuerAltName =>
+ alias : list of ref GeneralName;
+ SubjectAltName =>
+ alias : list of ref GeneralName;
+ NameConstraints =>
+ permitted : list of ref GSubtree;
+ excluded : list of ref GSubtree;
+ PolicyConstraints =>
+ require : int;
+ inhibit : int;
+ CRLNumber =>
+ curr : int;
+ ReasonCode =>
+ code : int;
+ InstructionCode =>
+ oid : ref ASN1->Oid; # hold instruction code field
+ InvalidityDate =>
+ date : int;
+ CRLDistributionPoint =>
+ ps : list of ref DistrPoint;
+ IssuingDistributionPoint =>
+ name : ref DistrPointName;
+ only_usercerts : int; # DEFAULT FALSE
+ only_cacerts : int; # DEFAULT FALSE
+ only_reasons : int;
+ indirect_crl : int; # DEFAULT FALSE
+ CertificateIssuer =>
+ names : list of ref GeneralName;
+ DeltaCRLIndicator =>
+ number : ref Keyring->IPint;
+ SubjectDirectoryAttributes =>
+ attrs : list of ref Attribute;
+ UnknownType =>
+ ext : ref Extension;
+ }
+
+ decode: fn(ext: ref Extension): (string, ref ExtClass);
+ encode: fn(et: self ref ExtClass, critical: int): ref Extension;
+ tostring: fn(et: self ref ExtClass): string;
+ };
+
+ # key usage
+ KeyUsage_DigitalSignature, KeyUsage_NonRepudiation, KeyUsage_KeyEncipherment,
+ KeyUsage_DataEncipherment, KeyUsage_KeyAgreement, KeyUsage_KeyCertSign,
+ KeyUsage_CRLSign, KeyUsage_EncipherOnly, KeyUsage_DecipherOnly : con iota << 1;
+
+ # CRL reason
+ Reason_Unspecified, Reason_KeyCompromise, Reason_CACompromise,
+ Reason_AffiliationChanged, Reason_Superseded, Reason_CessationOfOperation,
+ Reason_CertificateHold, Reason_RemoveFromCRL : con iota << 1;
+
+ # General Name
+ GeneralName: adt {
+ pick {
+ otherName or # [0]
+ rfc822Name or # [1]
+ dNSName or # [2]
+ x400Address or # [3]
+ uniformResourceIdentifier => # [6]
+ str : string;
+ iPAddress => # [7]
+ ip : array of byte;
+ registeredID => # [8]
+ oid : ref ASN1->Oid;
+ ediPartyName => # [5]
+ nameAssigner : ref Name; # [0]
+ partyName : ref Name; # [1]
+ directoryName => # [4]
+ dir : ref Name;
+ }
+
+ tostring: fn(g: self ref GeneralName): string;
+ };
+
+ # security policies
+ PolicyInfo: adt {
+ oid : ref ASN1->Oid;
+ qualifiers : list of ref PolicyQualifier;
+
+ tostring: fn(pi: self ref PolicyInfo): string;
+ };
+
+ PolicyQualifier: adt {
+ oid : ref ASN1->Oid;
+ value : array of byte; # OCTET STRING; OPTIONAL
+
+ tostring: fn(pq: self ref PolicyQualifier): string;
+ };
+
+ GSubtree: adt {
+ base : ref GeneralName;
+ min : int;
+ max : int;
+
+ tostring: fn(gs: self ref GSubtree): string;
+ };
+
+ # crl distribution point
+ # with known reason code
+ # Unused [0], KeyCompromise [1], CACompromise [2], AffilationChanged [3],
+ # Superseded [4], CessationOfOperation [5], CertificateHold [6]
+ DistrPoint: adt{
+ name : ref DistrPointName;
+ reasons : int;
+ issuer : list of ref GeneralName;
+
+ tostring: fn(dp: self ref DistrPoint): string;
+ };
+
+ DistrPointName: adt {
+ full_name : list of ref GeneralName;
+ rdname : list of ref RDName;
+ };
+
+ Attribute: adt {
+ id : ASN1->Oid;
+ value : array of byte;
+ };
+};
+
+#X509Attribute: module {
+#
+# ## Attribute Certificate
+#
+# AttrCert: adt {
+# version : int; # default v1
+# base_certid : ref IssuerSerial; # [0]
+# subject_name : list of ref GeneralName; # [1]
+# issuer : list of ref GeneralName;
+# serial_number : ref IPint;
+# validity : ref Validity;
+# attrs : list of ref Attribute;
+# issuer_uid : array of byte; # OPTIONAL
+# exts : list of ref Extension; # OPTIONAL
+# };
+#
+# IssuerSerial: adt {
+# issuer : list of ref GeneralName;
+# serial : ref IPint;
+# issuer_uid : array of byte; # OPTIONAL
+# };
+#};
diff --git a/module/xml.m b/module/xml.m
new file mode 100644
index 00000000..ee83a0c1
--- /dev/null
+++ b/module/xml.m
@@ -0,0 +1,78 @@
+Xml: module {
+ PATH: con "/dis/lib/xml.dis";
+ Item: adt {
+ fileoffset: int;
+ pick {
+ Tag =>
+ name: string;
+ attrs: Attributes;
+ Text =>
+ ch: string;
+ ws1, ws2: int;
+ Process =>
+ target: string;
+ data: string;
+ Doctype =>
+ name: string;
+ public: int;
+ params: list of string;
+ Stylesheet =>
+ attrs: Attributes;
+ Error =>
+ loc: Locator;
+ msg: string;
+ }
+ };
+
+ Locator: adt {
+ line: int;
+ systemid: string;
+ publicid: string;
+ };
+
+ Attribute: adt {
+ name: string;
+ value: string;
+ };
+
+ Attributes: adt {
+ attrs: list of Attribute;
+
+ all: fn(a: self Attributes): list of Attribute;
+ get: fn(a: self Attributes, name: string): string;
+ };
+
+ Mark: adt {
+ estack: list of string;
+ line: int;
+ offset: int;
+ readdepth: int;
+
+ str: fn(m: self ref Mark): string;
+ };
+
+ Parser: adt {
+ in: ref Bufio->Iobuf;
+ eof: int;
+ lastnl: int;
+ estack: list of string;
+ loc: Locator;
+ warning: chan of (Locator, string);
+ errormsg: string;
+ actdepth: int;
+ readdepth: int;
+ fileoffset: int;
+ preelem: string;
+ ispre: int;
+
+ next: fn(p: self ref Parser): ref Item;
+ up: fn(p: self ref Parser);
+ down: fn(p: self ref Parser);
+ mark: fn(p: self ref Parser): ref Mark;
+ atmark: fn(p: self ref Parser, m: ref Mark): int;
+ goto: fn(p: self ref Parser, m: ref Mark);
+ str2mark: fn(p: self ref Parser, s: string): ref Mark;
+ };
+ init: fn(): string;
+ open: fn(f: string, warning: chan of (Locator, string), preelem: string): (ref Parser, string);
+};
diff --git a/module/xpointers.m b/module/xpointers.m
new file mode 100644
index 00000000..491beffe
--- /dev/null
+++ b/module/xpointers.m
@@ -0,0 +1,67 @@
+Xpointers: module
+{
+ PATH: con "/dis/lib/w3c/xpointers.dis";
+
+ One, Ole, Oge, Omul, Odiv, Omod, Oand, Oor, Oneg,
+ Onodetype, Onametest, Ofilter, Opath: con 'A'+iota;
+
+ # axis types
+ Aancestor,
+ Aancestor_or_self,
+ Aattribute,
+ Achild,
+ Adescendant,
+ Adescendant_or_self,
+ Afollowing,
+ Afollowing_sibling,
+ Anamespace,
+ Aparent,
+ Apreceding,
+ Apreceding_sibling,
+ Aself: con iota;
+
+ Xstep: adt {
+ axis: int; # Aancestor, ... (above)
+ op: int; # Onametest or Onodetype
+ ns: string;
+ name: string;
+ arg: string; # optional parameter to processing-instruction
+ preds: cyclic list of ref Xpath;
+
+ text: fn(nil: self ref Xstep): string;
+ axisname: fn(i: int): string;
+ };
+
+ Xpath: adt {
+ pick{
+ E =>
+ op: int;
+ l, r: cyclic ref Xpath;
+ Fn =>
+ ns: string;
+ name: string;
+ args: cyclic list of ref Xpath;
+ Var =>
+ ns: string;
+ name: string;
+ Path =>
+ abs: int;
+ steps: list of ref Xstep;
+ Int =>
+ val: big;
+ Real =>
+ val: real;
+ Str =>
+ s: string;
+ }
+ text: fn(nil: self ref Xpath): string;
+ };
+
+ init: fn();
+ framework: fn(s: string): (string, list of (string, string, string), string);
+
+ # predefined schemes
+ element: fn(s: string): (string, list of int, string);
+ xmlns: fn(s: string): (string, string, string);
+ xpointer: fn(s: string): (ref Xpath, string);
+};