//NSilUtil.bcpl -- Utilities used throughout SIL system

get "sysdefs.d"
get "nsil.defs"

let FlushList(link) be
[
until link eq 0 do
[
let tl = link>>item.link
link>>item.link = -1
link = tl
]

]
and AddToList(lvptr) be
[
let l = Length(NewItem)+NewItem
if Usc(l,SpaceTop)gr 0 then
[
CallSwat("Space Exhaused")
finish
]

NewItem>>item.link = @lvptr
@lvptr = NewItem
NewItem=l
]

and IncrementCoords(obj,xinc,yinc) be
[
obj>>item.xmin = obj>>item.xmin+xinc
obj>>item.xmax = obj>>item.xmax+xinc
obj>>item.ymin = obj>>item.ymin+yinc
obj>>item.ymax = obj>>item.ymax+yinc
]

and Length(block) = valof //returns the length of an item
[
if block>>item.font ne 14 then resultis 6+(block>>item.string.length)/2
resultis 5
]



// String routines of various sorts

and AppendC(char,string) be
[
let st = string>>str.length +1
string>>str.char↑st = char
string>>str.length = st
]

and AppendS(sts,std) be //copy from source to destination
[
let dl = std>>str.length
for i = 1 to sts>>str.length do
[
dl = dl+1
std>>str.char↑dl = sts>>str.char↑i
]
std>>str.length = dl
]

and AppendN(num,str) be //decimal number
[
let chout = false
let rtab = table [ 10000; 1000; 100;10; 1; ]
for i = 0 to 4 do
[
let radp = rtab!i
if radp gr num then
[
if chout then AppendC($0,str)
loop
]

//number ge radp
let ch = $0

until num ls radp do
[
ch = ch+1
num = num-radp
]

chout = true
AppendC(ch,str)
]
if not chout then AppendC($0,str) //nothing output yet
]
and AppendB(num, str) be//octal number, no zero suppression
[
for i = 15 to 0 by -3 do
AppendC(((num rshift i)&7)+$0,str)
]

and StEq(s1,s2,ulEqual; numargs na) = valof //string compare
[
if s1>>str.length ne s2>>str.length then resultis false
ulEqual=(na ne 2)? 177737b,-1
for i = 1 to s1>>str.length do
if ((s1>>str.char↑i xor s2>>str.char↑i)&ulEqual) ne 0 then resultis false
resultis true
]


and WSS(stream,string) be
[
for i = 1 to string>>str.length do Puts(stream,string>>str.char↑i)
]