// TableMaker.bcpl -- converts a file into a table contained in a loadable .br file
// Last modified April 6, 1982 1:12 PM by Taft
// Bldr TableMaker GP
get "Streams.d"
external
[
SetupReadParam; ReadParam
OpenFile; Closes; Resets; Endofs; Puts; ReadBlock; WriteBlock; FileLength; Wl
MoveBlock; Zero
]
//----------------------------------------------------------------------------
structure BRFile: // Bcpl binary format
//----------------------------------------------------------------------------
[
bcplVersionNumber word
fileLength word
blank word // must be zero
nameTableOffset word
blank word // must be zero
labelTableOffset word
blank word // must be zero
codeOffset word
blank word // must be zero
chainTableOffset word
blank word // must be zero
zchainTableOffset word
blank word 3 // must be zero
labelTable word 3 =
[
labelCount word // must be 1
labelNameNumber word // must be 1
labelPC word // must be 1
]
chainTable word 1 // must be zero
zchainTable word 1 // must be zero
nameTable word 3 =
[
nameCount word // must be 1
nameDescriptor word // must be 140b
blank word
nameString word 0 // actually @String
]
code word 2 =
[
codeLength word
codeFirst word 1 // should be zero
data word 0
]
]
manifest
[
lenBRFile = offset BRFile.nameString/16 // + name string + data
bcplVersionNumber = 2 lshift 8
]
structure String: [ length byte; char↑1,1 byte ]
//----------------------------------------------------------------------------
let TableMaker() be
//----------------------------------------------------------------------------
[
let inputFileName, outputFileName, staticName = vec 127, vec 127, vec 127
inputFileName!0 = 0; outputFileName!0 = 0; staticName!0 = 0
let string, switchVec = vec 127, vec 127
SetupReadParam()
[ // repeat
if ReadParam($P, 0, string, switchVec, true) eq -1 then break
let destString = selecton switchVec!0 into
[
case 0: inputFileName
case 1:
selecton switchVec!1 into
[
case $I: case $i: inputFileName
case $O: case $o: outputFileName
case $S: case $s: staticName
default: Fail("Undefined switch")
]
default: Fail("Too many switches")
]
MoveBlock(destString, string, string>>String.length rshift 1 +1)
] repeat
let inputFile = 0
if inputFileName!0 ne 0 then
inputFile = OpenFile(inputFileName, ksTypeReadOnly, wordItem)
if inputFile eq 0 then Wl("Input file not found.*n")
if inputFile eq 0 then
inputFile = ReadParam("IW", "Input file: ", inputFileName)
for i = 1 to inputFileName>>String.length do
if inputFileName>>String.char↑i eq $. then
[ inputFileName>>String.length = i-1; break ]
if staticName!0 eq 0 then
MoveBlock(staticName, inputFileName, inputFileName>>String.length rshift 1 +1)
if outputFileName!0 eq 0 then outputFileName = inputFileName
let dot = 0
for i = 1 to outputFileName>>String.length do
if outputFileName>>String.char↑i eq $. then
[ dot = i; break ]
if dot eq 0 then
[
dot = outputFileName>>String.length +1
outputFileName>>String.char↑dot = $.
outputFileName>>String.char↑(dot+1) = $b
outputFileName>>String.char↑(dot+2) = $r
outputFileName>>String.length = dot+2
]
let outputFile = OpenFile(outputFileName, ksTypeWriteOnly, wordItem)
if outputFile eq 0 then Fail("Can't open output file")
let fileLength = vec 1
FileLength(inputFile, fileLength)
let dataLength = fileLength!0 lshift 15 + fileLength!1 rshift 1
if (fileLength!1 & 1) ne 0 then dataLength = dataLength+1
Resets(inputFile)
WriteBRFileHeader(outputFile, dataLength, staticName)
until Endofs(inputFile) do
[
manifest lenDataVec = 12*256
let data = vec lenDataVec
let words = ReadBlock(inputFile, data, lenDataVec)
WriteBlock(outputFile, data, words)
]
Closes(inputFile)
Closes(outputFile)
]
//----------------------------------------------------------------------------
and Fail(message) be
//----------------------------------------------------------------------------
[
Wl(message)
Wl("Command syntax is: TableMaker inputFile outputFile/o staticName/s")
abort
]
//----------------------------------------------------------------------------
and WriteBRFileHeader(stream, dataLength, labelName) be
//----------------------------------------------------------------------------
// ripped off from LoadMB.bcpl, courtesy of Peter Deutsch
[
let brFile = vec lenBRFile; Zero(brFile, lenBRFile)
let nameLength = labelName>>String.length/2+1
brFile>>BRFile.bcplVersionNumber = bcplVersionNumber
brFile>>BRFile.fileLength = offset BRFile.data/16 + nameLength + dataLength
brFile>>BRFile.nameTableOffset = offset BRFile.nameTable/16
brFile>>BRFile.labelTableOffset = offset BRFile.labelTable/16
brFile>>BRFile.codeOffset = offset BRFile.code/16 + nameLength
brFile>>BRFile.chainTableOffset = offset BRFile.chainTable/16
brFile>>BRFile.zchainTableOffset = offset BRFile.zchainTable/16
brFile>>BRFile.labelCount = 1
brFile>>BRFile.labelNameNumber = 1
brFile>>BRFile.labelPC = 1
brFile>>BRFile.nameCount = 1
brFile>>BRFile.nameDescriptor = 140b
WriteBlock(stream, brFile, lenBRFile)
WriteBlock(stream, labelName, nameLength)
Puts(stream, dataLength+1) // codeLength
Puts(stream, 0) // codeFirst
]