// Dirs.sr
// Last modified October 25, 1979 8:36 PM by Taft
get "BFS.DEF";
get "bravo1.df";
get "q.DF";
get "st.DF";
get "AltoFileSys.d";
get "VM.DF";
get "dir.DF";
// Incoming Procedures
external [
movec;
move;
flushvm;
Enqueue;
remakevmtb;
ScanPages;
errhlta
Dequeue;
umin;
sbwsize;
ugt;
ult;
RealDA
min;
divmod;
stput;
stcopy;
AllocVm;
];
// Incoming Statics
external [
dnbp;
macbp;
rgvpa;
fpSysDir;
rgbs
diskKd
rglastused
defaultVersionsKept
];
// Outgoing Procedures
external [
FindFptr;
NormalizeSbFile;
FMatchDe;
DirLkup;
InitNmd;
VerNext;
AppendVer;
];
manifest [
pidLlNmd = 5
pidCwRem = 8
pidBuf = 9
pidFnewDe = 10
pidCwNeeded = 11
pidCwRead = 12
pidDe = 13
pidWaDe = 14
pidCwMac = 15
waNil = -1
]
// F I N D F P T R
//
let FindFptr(cfaDirEnd,llNmd,mpPgnDa,pgnMax) be
[ let cwRem = 0; let buf = 0; let fnewDe = true; let cwNeeded = nil;
let cwRead = 0; let de = vec ldeMax; let waDe = nil; let cwMac = nil
let fptrDir = lv (cfaDirEnd >> CFA.fp)
// SortAndNorm(llNmd)
cfaDirEnd >> CFA.fa.da = RealDA(cfaDirEnd >> CFA.fp.leaderVirtualDa);
cfaDirEnd >> CFA.fa.pageNumber = 0;
let poolBuf = vec maxbp*lBuf
let qBufFree = vec lQ; AllocVm(qBufFree,poolBuf,4);
let tc = ScanPages(cfaDirEnd,qBufFree,TcCollectDe,mpPgnDa,pgnMax)
]
// S O R T A N D N O R M
// the sort got tossed as not worth it
// and SortAndNorm(llNmd) = valof
// [ let nmd = @llNmd
// while nmd ne 0 do
// [ let sbFile = lv nmd >> NMD.asbFile
// NormalizeSbFile(sbFile,lv nmd >> NMD.ver)
// if nmd >> NMD.ver ne 0 then nmd >> NMD.vc eq vcExact
// let nmdNext = nmd >> NMD.next;
// let pLinkPrev = lv tll
// [ let nmd1 = @pLinkPrev
// let comp = valof
// [ if nmd1 eq 0 then
// resultis 1
// let tsb = lv nmd1 >> NMD.asbFile
// for i = 0 to sbwsize(sbFile)-1 do
// [ let td = sbFile ! i-tsb ! i
// unless td eq 0 then
// resultis td
// ]
// resultis 0
// ]
// if comp eq 0 then errhlt("sb=")
// if comp gr 0 then
// [ nmd >> NMD.next = nmd1
// @pLinkPrev = nmd
// break
// ]
// pLinkPrev = @pLinkPrev
// ] repeat
// nmd = nmd >> NMD.next
// ]
// ]
// T C C O L L E C T D E
//
and TcCollectDe(zone,Freturn) = valof
[ let scanParams = zone >> CBZ.extra
let fm = scanParams >> SCP.fmCaller
let de = fm ! pidDe
[ if Freturn(zone) then
resultis tcNotDone;
if fm ! pidCwRem le 0 then
[ if fm ! pidCwRem ls 0 then errhlta(198)
unless fm ! pidBuf eq 0 then
[ Enqueue(scanParams >> SCP.qBufFree,fm ! pidBuf)
if ((fm ! pidBuf) >> BUF.numChars ne #1000) then
resultis tcDone
]
fm ! pidBuf = Dequeue(scanParams >> SCP.qBufRead)
test fm ! pidBuf eq 0 ifnot
[ fm ! pidCwRem = ((fm ! pidBuf) >> BUF.numChars) rshift 1
fm ! pidCwMac = fm ! pidCwRem
]
ifso resultis tcToYou
]
let bcw = fm ! pidCwMac-fm ! pidCwRem
let ca = (fm ! pidBuf) >> BUF.ca+bcw
if fm ! pidFnewDe then
[ fm ! pidCwNeeded = ca >> DE.l
fm ! pidFnewDe = false
fm ! pidCwRead = 0
@de = @ca
if fm ! pidCwNeeded eq 0 then resultis tcDone
fm ! pidWaDe = (((fm ! pidBuf) >> BUF.pgn-1) lshift 8)+bcw
]
let tcw = umin(fm ! pidCwNeeded,fm ! pidCwRem)
unless de >> DE.ty eq tyDeFree then
move(ca,de+fm ! pidCwRead,tcw)
fm ! pidCwNeeded = fm ! pidCwNeeded-tcw
fm ! pidCwRem = fm ! pidCwRem-tcw
fm ! pidCwRead = fm ! pidCwRead+tcw
if fm ! pidCwNeeded eq 0 then
[ FMatchDe(de,fm ! pidWaDe,fm ! pidLlNmd)
fm ! pidFnewDe = true
]
] repeat
]
// F M A T C H D E
//
and FMatchDe(de,waDe,llNmd) = valof
[ let ver = nil; let nmd = @llNmd
while nmd ne 0 do
[ test de >> DE.ty eq tyDeFree ifso
[ if (de >> DE.l gr nmd >> NMD.ldeFree) & (nmd >> NMD.waDeFree eq waNil) then
[ nmd >> NMD.waDeFree = waDe
resultis false
]
]
ifnot [ if de >> DE.l gr ldeMax then errhlta(199)
let tsb = lv nmd >> NMD.asbFile
let feq = valof
[
// this check is just for efficiency
unless (de>>DE.asbFile.ch↑0 & 137B) eq (tsb>>SB.ch↑0 & 137B) resultis false
let sbFile = lv de >> DE.asbFile;
NormalizeSbFile(sbFile,lv ver)
if ver eq 0 then ver = 1
let cwSb = sbwsize (sbFile)
for i = 0 to cwSb-1 do
[
unless (sbFile!i & 157737B) eq (tsb!i & 157737B) then
resultis false
]
resultis true
]
if feq then
[ let vcWanted = nmd >> NMD.vc
let fmove = false
if (vcWanted eq vcExact) then
test (ver eq nmd >> NMD.ver) ifso
fmove = true
ifnot resultis false
nmd >> NMD.cver = nmd >> NMD.cver+1
unless ugt(ver,nmd >> NMD.verMin) then
[ nmd >> NMD.verMin = ver
if vcWanted eq vcOldest then
fmove = true
]
unless ult(ver,nmd >> NMD.verMac) then
[ nmd >> NMD.verMac = ver
if vcWanted eq vcNewest then
fmove = true
]
if fmove then
[ nmd >> NMD.ver = ver
nmd >> NMD.waDe = waDe
move(lv de >> DE.afptr,lv nmd >> NMD.afptr,lFP)
// resultis false
]
// resultis false
]
]
nmd = nmd >> NMD.next
]
resultis false
]
// N O R M A L I Z E S B F I L E
//
and NormalizeSbFile(sbFile,lvver,sbDest; numargs na) be
[ if na ls 3 then sbDest = sbFile
let fversOn = defaultVersionsKept ne 0
let ver = 0; let finVer = false; let ichLast = nil
let lsb = sbFile >> SB.cch
let ch = nil
for ich = 0 to lsb-1 do
[ ch = sbFile >> SB.ch ↑ ich
// sbDest >> SB.ch ↑ ich = ch % #40
test ch eq $. ifso
loop
ifnot test (ch eq $!) & fversOn ifso
[ ver = 0
ichLast = ich
finVer = true
]
ifnot test finVer & (ch le $9) & (ch ge $0) ifso
ver = ver*10+(ch-$0)
ifnot [ finVer = false; ver = 0]
]
unless finVer & (ver ne 0) then ichLast = lsb-((ch eq $.) ? 1,0)
sbDest >> SB.ch ↑ ichLast = $.
sbDest >> SB.cch = ichLast+1
if ichLast << odd then
sbDest >> SB.ch ↑ (ichLast+1) = 0
// if ver eq 0 then ver = 1
if na gr 1 then @lvver = ver
]
// D I R L K U P
//
// and DirLkup(sb,nmd,mpPgnDa,pgnMax; numargs na) = valof
// [ FindFptr(fpSysDir,lv nmd,mpPgnDa,pgnMax)
// resultis (nmd >> NMD.cver gr 0)
// ]
// I N I T N M D
//
and InitNmd(nmd,lnmd,sb,vc) be
[ if vc eq vcNew then vc = vcOldest
if vc eq vcNewestOrNew then vc = vcNewest
movec(nmd,nmd+lnmd-1,0) // inits cver, ver, vermin, etc
nmd >> NMD.verMin = -1
nmd >> NMD.vc = vc
nmd >> NMD.waDeFree = waNil
let sbFile = lv nmd >> NMD.asbFile
stcopy(sbFile,sb)
nmd >> NMD.next = 0
NormalizeSbFile(sbFile,lv nmd >> NMD.ver)
let lsb = sbwsize(sbFile)
nmd >> NMD.ldeFree = ovhDe+lsb+3
if nmd >> NMD.ver ne 0 then nmd >> NMD.vc = vcExact
]
// V E R N E X T
//
and VerNext(nmd) = valof
[ if defaultVersionsKept eq 0 then resultis 1
if nmd >> NMD.cver eq 0 then resultis 1
resultis nmd >> NMD.verMac+1
]
// A P P E N D V E R
//
and AppendVer(sbFile,ver) be
[ if (defaultVersionsKept eq 0) then return
if ver eq 0 then ver = 1
let ich = sbFile >> SB.cch
if (sbFile >> SB.ch↑(ich-1)) eq $. then
ich = ich-1
stput(sbFile,ich, $!)
ich = ich+1
divmod(ver,1000,lv ver)
let divor = 100; let fstarted = false
while divor ne 0 do
[ let digit = divmod(ver,divor,lv ver)
divor = divor/10
if fstarted % (digit ne 0) then
[ stput(sbFile,ich,digit+$0)
ich = ich+1
fstarted = true
]
]
stput(sbFile,ich, $.)
sbFile >> SB.cch = ich+1
]