// QVECS.SR	End of file vectors

get "BRAVO.DF";
get "CHAR.DF";
get "DISPLAY.DF";
get "GINN.DF"

// Incoming procedures

external
	[
	getint
	makelist
	deletea
	setparacp
	paraspec
	setpagecp
	setpagenum
	setparaspec
	macpara
	macpage
	insertstring
	growlist
	bubblesegs
	stsize
	stget
	forgetspec
	ckspecs
	getvch
	errhlt
	hpfree
	ugt
	ult
	puts
	stnum
	]

// Incoming statics

external
	[
	rgpara
	rgspec
	rgpage
	rgpagenum
	rgreadonly
	rgprogram
	vcp
	vchremain
	vdoc
	rgmaccp
	fdebug
	]
// Qutgoing procedures

external
	[
	qreadfilev
	qwritefilev;
	]

// Qutgoing statics

// R E A D F I L E V // **
//
let qreadfilev(doc, cpfirst, cplast) be
[
// example per vector:		<ctrlX>&2P0,31;00010!#&@<cr>
// repeat:	check for password at eof -- if absent, break
//		read in length from eof, reset read pointer
//		read in number of elements and list type
//		parse list, attaching results to doc
//		deletea all that was read above
manifest [ passl=5; lenl=5 ]
let anylist, items, listype, ti, siz, tcp = nil, nil, nil, nil, nil, nil
let list, nsegs, cppast = nil, nil, nil
let hasparas = false
let nparas = nil
vcp = 0
vchremain = 0
vdoc = doc
getvch() // kludge to try and get around bug with bigger stack & vm
	[
	cppast = cplast + 1
	if ult(cppast - cpfirst, passl) then break // $$
	vcp = cppast-passl
	vchremain = 0
	vdoc = doc
	ti = false
	for i = 0 to passl-1 do
		if getvch() ne table[ $!; $#; $&; $@; chcr ] ! i
			then ti = true ;
	if ti then break ;
	vcp = cppast-passl-lenl
	siz = getint(doc)
	tcp = cppast-passl-lenl-siz
	vcp = tcp
	vchremain = 0
	for i = 0 to 1 do if getvch() ne table[ $*032; $& ] ! i
		then errhlt("Mz&")
	siz = 1 + getint(doc, 10, $0, lv listype) ;
	switchon listype into
		[
	case $P:		// P for paragraph
		hasparas = true
		nparas = siz-1
		list = rgpara
		nsegs = 1
		endcase
	case $S:		// S for section ie page
		list = rgpage
		nsegs = 1
		endcase
	case $N:		// N for pagenum
		list = rgpagenum
		nsegs = 1
		endcase
	case $R:		// R for Read Only
		list = rgreadonly
		nsegs = 1
		endcase
	default:
		errhlt("UVT")
		]
	if list ! doc then hpfree(list ! doc)
	list ! doc = 0
	anylist = makelist(siz, nsegs, listbase, true) ;
	list ! doc = anylist
	ti = 0
	let cbreak = 0 ;
	items = anylist + listbase ;
		[
		cbreak = getvch()
		if ti ge siz-1 then errhlt("VTL") ;
		items ! ti = getint(doc, 10, cbreak, lv cbreak) ;
		if ti & not ugt(items ! ti, items ! (ti-1)) then
			errhlt("VBS") ;
		ti = ti + 1
		] repeatwhile cbreak eq $,
	if ti eq 0 % items ! 0 ne 0 then errhlt("VNZ")
	anylist >> LIST.siz = ti + 1 ;
	deletea(doc, tcp, cplast) ;
	cplast = tcp-1	
	] repeat
setparacp(doc, macpara(doc)-1, rgmaccp ! doc)
setpagecp(doc, macpage(doc)-1, rgmaccp ! doc)
setpagenum(doc, macpage(doc)-1, rgmaccp ! doc)
test hasparas
ifso	deletea(doc, cplast + 1, rgmaccp ! doc -1) // extra dummy para
ifnot	[
	nparas = 2
	insertstring(doc, cplast+1, "*032*N")
	growlist(rgpara+doc, 1, 10, 1, listbase)
	bubblesegs(macpara(doc) - 1, 1, 0, rgpara!doc + listbase)
	setparacp(doc, 1, rgmaccp ! doc - 2)
	]
rgprogram ! doc = not hasparas
for para = 0 to (rgspec!doc) >> LIST.siz-1 do
		forgetspec(doc, para)
growlist(rgspec+doc, nparas-1, 10, 1, listbase)
bubblesegs(macpara(doc)-nparas + 1, nparas-1, 0, rgspec!doc + listbase)
if (rgpage!doc) >> LIST.siz ne (rgpagenum!doc) >> LIST.siz then
	errhlt("MPV")
if fdebug then ckspecs()
]
// W R I T E F I L E V // **
//
and qwritefilev(doc, fnstream) be
[
// for each list attached to doc, write onto fnstream:
//		ctrlX &
//		its type
//		its contents unparsed
//		the length of the above
//		the password
//		CR
qwritelist(fnstream, rgpara ! doc, $P)
qwritelist(fnstream, rgpage ! doc, $S)
qwritelist(fnstream, rgpagenum ! doc, $N)
if rgreadonly ! doc then qwritelist(fnstream, rgreadonly ! doc, $R)
]

and qwritelist(fnstream, list, listype) be
[
let stn = vec 4
unless list do return
manyputs(fnstream, "*032&")
let siz = 2
stnum(stn, list >> LIST.siz - 1)
manyputs(fnstream, stn)
siz = siz + stsize(stn)
puts(fnstream, listype)
siz = siz + 1
let listdata = list + listbase
for i = 0 to list >> LIST.siz - 2 do
	[
	if i then
		[
		puts(fnstream, $,)
		siz = siz + 1
		]
	stnum(stn, listdata ! i)
	manyputs(fnstream, stn)
	siz = siz + stsize(stn)
	]
puts(fnstream, $;)
siz = siz + 1
stnum(stn, siz)
for i = stsize(stn)+1 to 5 do puts(fnstream, $0)
manyputs(fnstream, stn)
manyputs(fnstream, "!#&@")
puts(fnstream, chcr)
]

and manyputs(fnstream, str) be
	for i = 0 to stsize(str)-1 do
		puts(fnstream, stget(str, i))