// rff.sr // Last modified October 25, 1979 6:54 PM by Taft get "BRAVO1.DF"; get "MSG.DF" // get "SELECT.DF" get "VM.DF" get "ALTOFILESYS.D" get "BFS.DEF" get "FORMAT.DF" // get "COM.DF" // get "RN1.DF" // Incoming Procedures external [ array errhlta errhlt movec VirtualDA move flushvm Enqueue remakevmtb TIMER ScanPages // waitforfd deallocfn MyFrame hpalloca fastscan getsintfast LengthQ Dequeue diskwritegroup getfb SetVab setsel ] // Incoming Statics external [ vxrightmargstd vxleftmargstd mpfnof vextendof macbp dnbp rgvpa rglastused vfloppy vchremain vlb char vpw rgfcode dnfun rgbs vdxtbStd selmain look1std look2std ] // Outgoing Procedures external [ readformattedfile; ]; // Outgoing Statics external [ vfn; vfc; vfb; vfpfirst; vfplast; vbpsrc; vmask; vmacfc; vfbfrparlast; vfcterm; parastat; vmacfr; rglook1; mpfrfc; rglook2; vtop; vcfree; lvterminate; rgbpfs; vbpoffb; vpi; vparlast; vfcfirst; mpbifc; mpbifb; vbi; rgmpbifc; rgmpbifb; vfc1; vfbloclast; sblabel; vfclast; parsacred; vfbfirst; vfblast; rgfcterm; rgfctrailer; vcpage; cpar; vfinhibit; vfabort vfOldtab vdxtb ]; // Local Statics static [ vfn; vfc; vfb; vfpfirst; vfplast; vbpsrc; vmask; vmacfc; vfbfrparlast; vfcterm; parastat; vmacfr; rglook1; mpfrfc; rglook2; vtop; vcfree; lvterminate; rgbpfs; vbpoffb; vpi; vparlast; vfcfirst; mpbifc; mpbifb; vbi; rgmpbifc; rgmpbifb; vfc1; sblabel; vfclast; parsacred; vbifirstrun; vpifirstrun; ffirstrun; vfbfirst; vfblast; rgfcterm; rgfctrailer; vcpage; cpar; vfinhibit; vfabort vfchlt = -1 num vfNewtable vfOldtab vdxtb vsiTtblprev ]; // Local Structure structure PDESC: [ look1 word look2 word fInLabel word fNumPending word char word itb word fGotItb word fBadformat word ] structure AB: // can't get df [ crid byte nrid byte ] // local manifest manifest [ chsp = $*S ctrlz = $Z-#100 lPDesc = (size PDESC)/16 cbpFree = 3 cbpread = 4; maxfrstd = #100; look1trailer = #20; look2trailer = 0; mphd = 1; runovhd = 3; maxfr = (#400)/runovhd maxpar = 100; pidChRemain = 6 pidFParse = 7 pidParaStatStd = 8 pidBuf = 9 pidBufBin = 10 pidQBufBinFree = 11 pidQBufBinUsed = 12 pidFcTrailer = 13 pidFcFirst = 14 pidPDesc = 15 pidTtbl = 16 pidTtblPrev = 17 pidCparBadformat = 18 pidAty = 19 ] structure Q: [ head word tail word ] manifest [ lQ = (size Q)/16 atyNil = 0 atyParse = 1 atyFbo = 2 abmsg = -3 mtyOw = -1 sph = 9; schar = 6; ] let readformattedfile(fnsrc, lvnumcharslast) = valof [ // pidChRemain = 6? let chRemain = 0; // can't find any reference to this let fParse = false let paraStatStd = vec 1+parovhd; let buf = 0; let bufBin = 0; let qBufBinFree = vec lQ; qBufBinFree>>Q.head = 0; let qBufBinUsed = vec lQ; qBufBinUsed>>Q.head = 0; let fcTrailer = -1; let fcFirst = 0; let pDesc = vec lPDesc let ttbl = vec lnttblMax let ttblPrev = vec lnttblMax let cparBadformat = 0 let aty = atyNil // ** there exist pid's for all locals above this line !!! paraStatStd>>PSTAT.siz = 1+parovhd; paraStatStd>>PSTAT.xrightmarg = vxrightmargstd paraStatStd>>PSTAT.xleftmarg = vxleftmargstd paraStatStd>>PSTAT.xleftmargf = -1 paraStatStd>>PSTAT.ypos = -1; paraStatStd>>PSTAT.spec = specstd; paraStatStd>>PSTAT.fOldtab = true; paraStatStd>>PSTAT.dxtb = vdxtbStd; paraStatStd>>PSTAT.ykeep = 0; paraStatStd>>PSTAT.label = 0; ttbl>>TTBL.cw = 1 let mpitbxtb = lv ttbl>>TTBL.ampitbxtb for titb = 0 to itbMax-1 do mpitbxtb ! titb = xtbNil vfNewtable = true vfOldtab = true vdxtb = vdxtbStd // initialization of maps let macbpread = cbpread; rglook1 = array(maxfr+5); rglook2 = array(maxfr+5); mpfrfc = array(maxfr+5); mpfrfc ! 0 = 0; vmacfr = 0; parastat = array(#400); mpbifc = array(#200); mpbifb = array(#200); sblabel = array(#200); vbi = -1; let macpos = (mpfnof ! fnscrfs)>>OF.macpos; unless macpos<>OF.rgda movec(cfaSrc, cfaSrc+lCFA-1, 0) cfaSrc>>CFA.fp.version = of>>OF.version; cfaSrc>>CFA.fp.leaderVirtualDa = VirtualDA(da); cfaSrc>>CFA.fa.da = da; move(lv (of>>OF.sn1), lv (cfaSrc>>CFA.fp.serialNumber), lSN) let poolBuf = array(macbp*lBuf) let qBufFree = vec lQ; qBufFree>>Q.head = 0; flushvm() let tBuf = poolBuf for bp = 0 to macbp-cbpFree-1 do [ tBuf>>BUF.ca = dnbp ! bp tBuf>>BUF.bp = bp tBuf>>BUF.pgn = 0 let qBuf = (bp ls macbpread) ? qBufFree, qBufBinFree Enqueue(qBuf, tBuf) tBuf = tBuf+lBuf rgvpa ! bp = -1 rglastused ! bp = -1; ] remakevmtb() let mpPgnDa = array(#202); // let mpPgnDa = lv (of>>OF.rgda) // let starttime = vec 2 // TIMER(starttime) let tc = ScanPages(cfaSrc, qBufFree, TcFileParser, mpPgnDa, #201) let pgnLast = cfaSrc>>CFA.fa.pageNumber // if vfloppy then // waitforfd(of>>OF.fda, 0, pgnLast, starttime); if cfaSrc>>CFA.fa.charPos eq #1000 then [ pgnLast = 130; goto rfffin; ] rfffin: test (tc eq tcByScanPages) % (tc eq tcAbort) ifso [ // tcByScanPages means file too big // tcAbort means parse error if (tc eq tcAbort) & (aty eq atyParse) then [ let ab = nil ab<>SEL.type = schar ] pgnLast = 130 // kludgy way of returning false // ifnot file too large ? ] ifnot [ // if cparBadformat ne 0 then // [ // message -- "Selected paragraph not in Bravo format[ - first of n]" // let ridFirstOf = rinil // let ridCpar = rinil // if cparBadformat gr 1 then // [ // ridFirstOf = 226 // let tsb = vec 5 // stnum(tsb, cparBadformat) // SetRegionW(vrlwsys, 0, tsb) // ridCpar<>OF.rgda), pgnLast+2); test fParse ifso [ vparlast>>PAR.nextpar = -1 EstablishFb(MyFrame()) mpbifc ! (vbi+1) = (pgnLast-1) lshift 9 + buf>>BUF.numChars mpbifb ! (vbi+1) = -1; let tphp = hpalloca(vbi+2); move(mpbifc, tphp, vbi+2); rgmpbifc ! fnsrc = tphp; tphp = hpalloca(vbi+2); move(mpbifb, tphp, vbi+2); rgmpbifb ! fnsrc = tphp; (mpfnof ! fnsrc)>>OF.macbi = vbi+1; ] ifnot (mpfnof ! fnsrc)>>OF.formatted = false; ] tBuf = poolBuf let vpa = nil for bp = 0 to macbp-cbpFree-1 do [ rglastused ! bp = 1; unless bp ls macbpread then loop rgvpa ! bp = -1 ] remakevmtb() mpfrfc = 0; @lvnumcharslast = cfaSrc>>CFA.fa.charPos resultis pgnLast; ] // F I L E P A R S E R // and TcFileParser(zone, fReturn) = valof [ [ if fReturn(zone) then resultis tcNotDone; let scanParams = zone>>CBZ.extra let fmRff = scanParams>>SCP.fmCaller let tc = TcTryGetBuf(zone) if tc ne tcNil then // ** some thing here to indicate error if ScanPages returns on this [ if (tc eq tcDone) & (fmRff ! pidFParse) & (FcOfBuf(fmRff) ne fmRff ! pidFcFirst) then [ fmRff ! pidAty = atyParse resultis tcAbort ] resultis tc; ] SetPters(fmRff) fastscan(ctrlz); fmRff ! pidChRemain = vchremain; unless vchremain do loop; fmRff ! pidFcTrailer = FcOfBuf(fmRff) InitParse(fmRff) scanParams>>SCP.TcScanProc = TcParseParagraph resultis tcNotDone ] repeat ] // P A R S E P A R A G R A P H // // Paragraph format is where has no CRs // and trailer format is ctrlZ then "jn7b12B14u7bU" then CR // means 5 changes starting with Justified text, // 7 chars later turn on Bold // 12 chars later turn off bold // 14 chars later turn on Ul // 7 chars later turn on Bold and turn off ul // n means no change since last version; N means has changed // there is an optional change count in front of the trailer; // if not present it is estimated and TcParseParagraph(zone, fReturn) = valof [ let fmRff = (zone>>CBZ.extra)>>SCP.fmCaller fmRff ! pidFParse = true let pDesc = fmRff ! pidPDesc let ttbl = fmRff ! pidTtbl let mpitbxtb = lv ttbl>>TTBL.ampitbxtb let itb = nil vchremain = 0 let chRemainOld = 0; [ if (vchremain eq 0) then [ fmRff ! pidChRemain = fmRff ! pidChRemain - chRemainOld if fReturn(zone) then resultis tcNotDone let tc = TcTryGetBuf(zone) if tc ne tcNil then [ if tc eq tcDone then [ fmRff ! pidAty = atyParse resultis tcAbort ] resultis tc; ] SetPters(fmRff) chRemainOld = vchremain ] test vlb ifso [ char = vpw>>lh; vlb = false; ] ifnot [ char = vpw>>rh; vlb = true; vpw = vpw+1; ] vchremain = vchremain-1; skipgetchar: unless pDesc>>PDESC.fNumPending do pDesc>>PDESC.char = char; let fcode = rgfcode ! (pDesc>>PDESC.char) let kind = fcode<>PDESC.fBadformat then test kind eq kcr ifso break ifnot loop let w = fcode<>PDESC.char = char; num = getsintfast(num, lv char) ; if (char eq -1) do [ pDesc>>PDESC.fNumPending = true; loop; ] if vfb ge #170 then [ until @nextDiskCommand eq 0 do loop SetVab(abmsg,mtyOw,227,50) fmRff ! pidAty = atyFbo resultis tcAbort ] MakeRun(fmRff, num, pDesc>>PDESC.look1, pDesc>>PDESC.look2); num = 0; pDesc>>PDESC.fNumPending = false; goto skipgetchar; case kcr: break case klook1: pDesc>>PDESC.look1 = un ? pDesc>>PDESC.look1 & not m, pDesc>>PDESC.look1 % m endcase; case kquad: parastat ! w = (parastat ! w) % m endcase case koffset: pDesc>>PDESC.char = char; unless pDesc>>PDESC.fNumPending then char = $0 num = getsintfast(num, lv char) ; if (char eq -1) do [ pDesc>>PDESC.fNumPending = true; loop; ] (lv (pDesc>>PDESC.look2))>>LOOK2.ofset = num; num = 0; pDesc>>PDESC.fNumPending = false; goto skipgetchar; case kfun: pDesc>>PDESC.char = char; unless pDesc>>PDESC.fNumPending then char = $0 num = getsintfast(num, lv char) ; if (char eq -1) do [ pDesc>>PDESC.fNumPending = true; loop; ] (lv (pDesc>>PDESC.look2))>>LOOK2.fun = num; dnfun ! num = true; num = 0; pDesc>>PDESC.fNumPending = false; goto skipgetchar; case kmeasure: pDesc>>PDESC.char = char; unless pDesc>>PDESC.fNumPending then char = $0 num = getsintfast(num, lv char)/mphd if (char eq -1) do [ pDesc>>PDESC.fNumPending = true; loop; ] unless pDesc>>PDESC.char eq $p then parastat ! w = num num = 0; pDesc>>PDESC.fNumPending = false; goto skipgetchar; case kparastatterm: endcase; case klabel: if pDesc>>PDESC.fInLabel then [ errhlta(9) // sblabel>>lh = i; // let len = sbwsize(sblabel); // siz = parastat>>PSTAT.siz; // move(sblabel, parastat+siz, len); // parastat>>PSTAT.siz = siz+len; ] pDesc>>PDESC.fInLabel = not pDesc>>PDESC.fInLabel; // i = 0; endcase; case kldln: pDesc>>PDESC.char = char; unless pDesc>>PDESC.fNumPending then char = $0 num = getsintfast(num, lv char) ; if (char eq -1) do [ pDesc>>PDESC.fNumPending = true; loop; ] parastat>>PSTAT.lead = num; num = 0; pDesc>>PDESC.fNumPending = false; goto skipgetchar; case kldhdr: pDesc>>PDESC.char = char; unless pDesc>>PDESC.fNumPending then char = $0 num = getsintfast(num, lv char) ; if (char eq -1) do [ pDesc>>PDESC.fNumPending = true; loop; ] parastat>>PSTAT.parspacing = num; num = 0; pDesc>>PDESC.fNumPending = false; goto skipgetchar; case kitb: pDesc>>PDESC.char = char; unless pDesc>>PDESC.fNumPending then char = $0 num = getsintfast(num, lv char) ; if (char eq -1) do [ pDesc>>PDESC.fNumPending = true; loop; ] if char eq $) then [ vdxtb = num vfOldtab = true num = 0; pDesc>>PDESC.fNumPending = false; endcase ] pDesc>>PDESC.itb = num pDesc>>PDESC.fGotItb = true num = 0; pDesc>>PDESC.fNumPending = false; goto skipgetchar; case kxtb: unless pDesc>>PDESC.fGotItb do goto badformat pDesc>>PDESC.char = char; unless pDesc>>PDESC.fNumPending then char = $0 num = getsintfast(num, lv char) ; if (char eq -1) do [ pDesc>>PDESC.fNumPending = true; loop; ] itb = pDesc>>PDESC.itb if itb ls 0 % itb ge itbMax then errhlta(10) if mpitbxtb ! itb ne num then [ mpitbxtb ! itb = num if itb ge ttbl>>TTBL.cw-1 then ttbl>>TTBL.cw = itb + 2 vfNewtable = true ] pDesc>>PDESC.fGotItb = false vfOldtab = false num = 0; pDesc>>PDESC.fNumPending = false; if char ne $) then goto badformat endcase case ktab: // if vfOldtab then // goto badformat pDesc>>PDESC.char = char; unless pDesc>>PDESC.fNumPending then char = $0 num = getsintfast(num, lv char); if (char eq -1) do [ pDesc>>PDESC.fNumPending = true; loop; ] (lv (pDesc>>PDESC.look2))>>LOOK2.tc = num num = 0; pDesc>>PDESC.fNumPending = false; goto skipgetchar; badformat: default: test pDesc>>PDESC.fInLabel ifso [ errhlta(11); ] ifnot unless char eq chsp do [ pDesc>>PDESC.fBadformat = true loop ] ] ] repeat fmRff ! pidChRemain = fmRff ! pidChRemain-chRemainOld+vchremain unless fmRff ! pidFcTrailer eq mpfrfc ! vmacfr do MakeRun(fmRff, fmRff ! pidFcTrailer - mpfrfc ! vmacfr, pDesc>>PDESC.look1, pDesc>>PDESC.look2); MakeParastat(fmRff, pDesc>>PDESC.look1, pDesc>>PDESC.look2); (zone>>CBZ.extra)>>SCP.TcScanProc = TcFileParser let tfc = FcOfBuf(fmRff) if pDesc>>PDESC.fBadformat then [ let cpar = fmRff ! pidCparBadformat if cpar eq 0 then [ setsel(selmain, fmRff ! pidFcFirst, tfc - 1) selmain>>SEL.type = sph ] fmRff ! pidCparBadformat = cpar + 1 ] fmRff ! pidFcFirst = tfc // test ((fmRff ! pidBuf)>>BUF.numChars ne #1000) & (fmRff ! pidChRemain eq 0) ifso // resultis tcDone // ifnot resultis tcNotDone ] // F T R Y G E T B U F // and TcTryGetBuf(zone) = valof [ let scanParams = zone>>CBZ.extra let fmRff = scanParams>>SCP.fmCaller unless fmRff ! pidChRemain eq 0 then resultis tcNil unless fmRff ! pidBuf eq 0 then [ if ((fmRff ! pidBuf)>>BUF.numChars ne #1000) then resultis tcDone Enqueue(scanParams>>SCP.qBufFree, fmRff ! pidBuf) fmRff ! pidBuf = 0 ] let qBufRead = scanParams>>SCP.qBufRead let cBufRead = LengthQ(qBufRead) test cBufRead eq 0 ifso resultis tcToYou ifnot [ let buf = Dequeue(qBufRead) fmRff ! pidBuf = buf; test buf>>BUF.pgn eq 0 ifso [ fmRff ! pidChRemain = 0 resultis TcTryGetBuf(zone) ] ifnot [ fmRff ! pidChRemain = buf>>BUF.numChars resultis tcNil ] ] ] // S E T P T E R S // and SetPters(fmRff) be [ vchremain = fmRff ! pidChRemain; let buf = fmRff ! pidBuf if buf>>BUF.pgn eq 0 then errhlta(12) let dFc = buf>>BUF.numChars-vchremain vpw = fmRff ! pidBuf>>BUF.ca+(dFc rshift 1); vlb = dFc<>BUF.pgn then errhlta(5) Enqueue(fmRff ! pidQBufBinFree, buf) ] vfbfirst = vfblast+1; buf = Dequeue(fmRff ! pidQBufBinFree) if buf eq 0 then errhlta(4) ] buf>>BUF.pgn = vfb+1 Enqueue(fmRff ! pidQBufBinUsed, buf) rgvpa ! (buf>>BUF.bp) = vpa remakevmtb(); let pfb = buf>>BUF.ca fmRff ! pidBufBin = buf vpi = 0; vmacfr = 0; mpfrfc ! 0 = fcfirst; vtop = pfb+#377; vcfree = #400-runovhd-1-fbovhd;// minus one for dnpi ! 0 vbi = vbi+1; ] // E S T A B L I S H F B // and EstablishFb(fmRff) be [ let buf = fmRff ! pidBufBin let pfb = buf>>BUF.ca; pfb>>FB.macfr = vmacfr; pfb>>FB.mpfrfc = ((offset FB.rvdnpi)/16)+vpi+1 pfb>>FB.rglook1 = pfb>>FB.mpfrfc+vmacfr+2; pfb>>FB.rglook2 = pfb>>FB.rglook1+vmacfr+1; move(mpfrfc, pfb+pfb>>FB.mpfrfc, vmacfr+1); move(rglook1, pfb+pfb>>FB.rglook1, vmacfr); move(rglook2, pfb+pfb>>FB.rglook2, vmacfr); (rgbs ! (buf>>BUF.bp))<>FB.rglook1) ! (-1) = 0; mpbifc ! vbi = mpfrfc ! 0; mpbifb ! vbi = vfb; (mpfnof ! fnscrfs)>>OF.macpos = (vfb+1) lshift 9; ] // M A K E R U N // and MakeRun(fmRff, dfc, look1, look2) be [ // ?? if ugt(endposplus1, vfcterm+1) then errhlt("fct") if dfc eq 0 then errhlt("dfc") if vcfree ls runovhd then EstAndGetFb(fmRff); if ffirstrun then [ vbifirstrun = vbi; vpifirstrun = vpi; ffirstrun = false; ] look1<>PSTAT.siz - offparParastat; if vfNewtable & not vfOldtab then [ let tmpitbxtb = lv ttbl>>TTBL.ampitbxtb let titb = itbMax-1 while titb ge 0 do [ if tmpitbxtb ! titb ne xtbNil then break titb = titb - 1 ] cwTtbl = titb + 2 ttbl>>TTBL.cw = cwTtbl siz = siz + cwTtbl move(ttbl, ttblPrev, lnttblMax) ] if (vcfree ls siz+runovhd+1) % vpi+1 ge maxpi then // plus 1 for dnpi entry EstAndGetFb(fmRff); let ttblBuf = vtop + 1 - cwTtbl vtop = vtop-siz let vpa = nil; let bifr = nil bifr<>PSTAT.par = bifr; parastat>>PSTAT.fcofpar = fmRff ! pidFcFirst; parastat>>PSTAT.fcofnextpar = fcNext; parastat>>PSTAT.trailerlength = fcNext-fmRff ! pidFcTrailer; if parastat>>PSTAT.xleftmargf eq -1 then parastat>>PSTAT.xleftmargf = parastat>>PSTAT.xleftmarg unless vfbfrparlast eq -1 then vparlast>>PAR.nextpar = bifr; let fbloc = nil; vparlast = vtop+1; let pfb = (fmRff ! pidBufBin)>>BUF.ca; parastat>>PSTAT.fOldtab = vfOldtab test vfOldtab ifso parastat>>PSTAT.dxtb = vdxtb ifnot [ if vfNewtable then [ vsiTtblprev = vfb lshift 8 + ttblBuf - pfb vfNewtable = false ] parastat>>PSTAT.siTtbl = vsiTtblprev ] fbloc<>FB.rvdnpi) dnpi ! vpi = fbloc; move(parastat+1, vtop+1, siz); if cwTtbl ne 0 then move(ttbl, ttblBuf, cwTtbl); vcfree = vcfree-(siz+1) vfbfrparlast<>PSTAT.trailerlength, look1, look2) if vbi ne vbifirstrun then [ let tbi = vbifirstrun; let tpi = vpifirstrun; [ let pfb = getfb(mpbifb ! tbi); (lv (pfb>>FB.rvdnpi)) ! tpi = fbloc; tbi = tbi+1; tpi = 0; ] repeatuntil tbi eq vbi ] vpi = vpi+1; ] // F C O F B U F // and FcOfBuf(fmRff) = valof [ let buf = fmRff ! pidBuf resultis ((buf>>BUF.pgn-1) lshift 9)+(buf>>BUF.numChars-fmRff ! pidChRemain) ] // I N I T P A R S E // and InitParse(fmRff) be [ ffirstrun = true; num = 0 move(fmRff ! pidParaStatStd, parastat, 1+parovhd) let pDescStd = table [ 0; 0; false; false; 0; 0; false; false ] pDescStd!0 = look1std; pDescStd!1 = look2std move(pDescStd, fmRff ! pidPDesc, lPDesc) sblabel ! 0 = 0; if fmRff ! pidChRemain eq 0 then errhlta(15) fmRff ! pidChRemain = fmRff ! pidChRemain-1 ]