//mtv.bcpl
get "streams.d"
external [
// OS
Wss; Puts; Resets; CallSwat
// MSYMB
TVtoString
// MCMD
DisplayError
// Defined here
StreamFromTextName
// Defined here for init only
TVSpareTVs; TVSpareTVec; PutTVs; ResetTVs; CloseTVs; BadTVsCall
]
structure TVS :
[ @ST
NoteP word
NoteArg word
]
static [ TVSpareTVs; TVSpareTVec ]
// Text Vec procedures
// procedures made external
let StreamFromTextName(Act, TV, DotExt, ksType, ItemSize) = valof
[ if TV!0 le 0 then DisplayError("Bad file name")
Resets(TVSpareTVs)
let DotFlag = false
for I = 1 to TV!0 do
[ let C = TV!I; if (C ge $a) & (C le $z) then C = C & 137B
Puts(TVSpareTVs, C); if C eq $. then DotFlag = true
]
if (not DotFlag) & (((DotExt!0) & #377) eq $.)
then Wss(TVSpareTVs, DotExt)
let S = Act(TVtoString(TVSpareTVec), ksType, ItemSize)
if S eq 0 then DisplayError("unable to open file")
resultis S
]
//
// local procedures
//
and PutTVs(Stream, Item) be
[ let TV = Stream>>TVS.par1
let MaxX = Stream>>TVS.par2
if TV eq 0 then return
let X = TV!0
if X < MaxX then
[ X = X + 1
TV!X = Item
TV!0 = X
]
if Stream>>TVS.NoteP ne 0 then
(Stream>>TVS.NoteP)(Stream, Stream>>TVS.NoteArg)
]
and ResetTVs(Stream, TV, N, NoteP, Arg; numargs Nargs) be
[ test Nargs ge 3
ifso
[ TV!0 = 0
Stream>>TVS.par1 = TV
Stream>>TVS.par2 = N
]
ifnot
[ let TV = Stream>>TVS.par1
if TV ne 0 then TV!0 = 0
if Stream>>TVS.NoteP ne 0 then
(Stream>>TVS.NoteP)(Stream, Stream>>TVS.NoteArg)
]
if Nargs eq 5 then
[ Stream>>TVS.NoteP = NoteP
Stream>>TVS.NoteArg = Arg
]
]
and CloseTVs(S) be
[ S>>TVS.par1 = 0
S>>TVS.par2 = 0
S>>TVS.NoteP = 0
]
and BadTVsCall(Stream) be CallSwat()