//prescan.bcpl -- used to allow analyze to do a gobble-like
//operation given a mess of files

get "sysdefs.d"
get "ana.defs"
static
[
L
R
TabCount = 6
]

external Wns

let OutSymbols() be
[
for i = 0 to htsize-1 do
[
let link = hashtab!i
until link eq 0 do
[
let ty = link>>strec.type
if (ty eq stComp)%(ty eq stSig) do
[
let foo = (ty eq stComp?#100000,0)%(page lshift 8)%(link>>strec.ucnt)
Puts(psfile,foo)
for j = 0 to (link>>strec.st.length)/2 do
Puts(psfile,(lv(link>>strec.st))!j)
]

link = @link
]
]
]


and PreScanOut(efn) be
[
//enter with psfile reset and storage initialized
//remember, the psfile is part of the file Swatee
if Gets(psfile) ne -1 then [ CallSwat("Scratch file lost by running swat"); finish ]
let sv = vec 128
let st = nil
[
st = Gets(psfile)
if st eq -1 then break // past the valid file
sv!0= Gets(psfile)
let sl=sv>>str.length
for i = 1 to sl/2 do sv!i = Gets(psfile) //read string
let stp = DefineSymbol(sv,(st ls 0)?stComp,stSig)
NewItem!0 = stp>>strec.rname
NewItem!1 = st
stp>>strec.rname = NewItem
NewItem=NewItem+2
] repeat
Closes(psfile)

let outfile = OpenFile(efn,ksTypeWriteOnly,1,0,0,0,SilZone)
//first put on Bravo control stuff for two collumn printing
Wss(outfile,"Page Numbers: Yes First Page: 1*n")
Wss(outfile,"Columns: 2 Edge Margin: .8*" Between Columns: .0*"*n")
Wss(outfile,"
Heading:*032")
Wss(outfile,"
q(0,4192)(1,5568)(2,6624)(3,7648)(4,8672)(5,9696)(6,10752)(7,11776)(8,12800)(9,13824)\f1*n")
Wss(outfile,efn)
Wss(outfile,
"*032y756q\f1*n")

//sort the symbol table
let nsyms = 0
for i = 0 to htsize-1 do
[
let link = hashtab!i
until link eq 0 do
[
nsyms = nsyms+1
NewItem!nsyms = link
link = @link
]
]

NewItem!0 = nsyms
Sort(NewItem,StCompFn)
Wss(outfile,"COMPONENTS:*n")
for i = 1 to NewItem!0 do
[
if (NewItem!i)>>strec.type eq stSig then loop
PrintStuff(NewItem!i,outfile,false)
]
Wss(outfile,"*032\f1*n") //Bravo Paragraph break
Wss(outfile,"*n*nSIGNAL NAMES:*n")
for i = 1 to NewItem!0 do
[
if (NewItem!i)>>strec.type eq stComp then loop
PrintStuff(NewItem!i,outfile,true)
]
Wss(outfile,"*032\f1*n") //Bravo Paragraph break
Closes(outfile)

]

and PrintStuff(stp,file,printcnt) be
[
let str = lv(stp>>strec.st)
Wss(file,"*n")
Wss(file,str)
Wss(file,":")
for i = str>>str.length to 10 do Puts(file,#40)//pad with spaces to take 2 tab widths
TabCount = 6
if str>>str.length ge 15 then TabCount = TabCount - 1
let link = stp>>strec.rname
InvertItems(link,file,printcnt)
]

and InvertItems(link,file,printcnt) be
[
if @link ne 0 then InvertItems(@link,file,printcnt)
if TabCount eq 0 do
[
Puts(file,$*n)
TabCount =6
Puts(file,$*t)
]
Puts(file,$*t); TabCount = TabCount - 1
Wns(file, ((link!1)rshift 8) ±, 2) //page number
if printcnt do
[
Puts(file,$()
Wns(file,(link!1) & #377) //count of uses on the page
Puts(file,$))
]
]

and StCompFn(stp1,stp2) = valof
[
let c1 = nil;let c2=nil;let comp = nil
let l1=stp1>>strec.st.length
let l2 = stp2>>strec.st.length
let lx = l1 ls l2?l1,l2
for k = 1 to lx do
[
c1= stp1>>strec.st.char↑k
c2= stp2>>strec.st.char↑k
if (c1 ge $a)&(c1 le $z) then c1 = c1+($A-$a)
if (c2 ge $a)&(c2 le $z) then c2 = c2+($A-$a)
comp = c1-c2
if comp ne 0 then break
]
if comp eq 0 then comp = l1-l2
resultis comp
]


and Sort(sv,cfn) be
[
let rp = nil
L = ((sv!0)/2)+1
R = sv!0
[
test L gr 1
ifso
[
L = L-1
rp = sv!L
]
ifnot
[
rp = sv!R
sv!R = sv!1
R = R-1
if R eq 1 then
[
sv!1 = rp
return
]
]

let j = L
let i = nil
[
i = j
j = j+j
if j ls R then if cfn(sv!j,sv!(j+1)) ls 0 then j = j+1

if j le R do
[
if cfn(sv!j,rp) le 0 then break
sv!i = sv!j
loop
]
break
] repeat

sv!i = rp
] repeat
]