DIRECTORY Ascii USING [CR, LF, SP, TAB], Basics, BasicTime, Commander USING [CommandProc, Handle, Register], CommandTool USING [DoCommand], FS, FileNames, Interpreter, IO, SymTab, RefText, TiogaAccess, List, Rope; UsingDependenciesImpl: CEDAR PROGRAM IMPORTS BasicTime, IO, FS, FileNames, Commander, CommandTool, Interpreter, RefText, Rope, List, TiogaAccess, SymTab ~ BEGIN ROPE: TYPE ~ Rope.ROPE; Scanner: TYPE ~ REF ScannerRep; ScannerRep: TYPE ~ RECORD [ stream: IO.STREAM, tokenKind: Kind, inputBuffer: REF TEXT, locationOfBufferStart: INT, tokenStart: NAT, tokenLength: NAT ]; inputBufferSize: NAT _ 2*1024; CreateScanner: PROC RETURNS [scanner: Scanner] ~ { scanner _ NEW[ScannerRep]; scanner.inputBuffer _ NEW[TEXT[inputBufferSize]]; }; SetScanner: PROC [scanner: Scanner, stream: IO.STREAM] ~ { scanner.stream _ stream; scanner.tokenKind _ whitespace; scanner.locationOfBufferStart _ IO.GetIndex[stream]; scanner.tokenStart _ 0; scanner.tokenLength _ 0; scanner.inputBuffer.length _ 0; }; Kind: TYPE ~ {identifier, special, charconst, string, whitespace, newline, comment, eof}; KindOf: PROC [c: CHAR] RETURNS [Kind] ~ { SELECT c FROM IN ['a..'z], IN ['A..'Z], IN ['0..'9], '$ => RETURN [identifier]; Ascii.SP, Ascii.TAB, Ascii.LF => RETURN [whitespace]; Ascii.CR => RETURN [newline]; ENDCASE => RETURN [special]; }; breakLoc: INT _ LAST[INT]; breakCount: INT _ 0; GetCharConstant: PROC [scanner: Scanner] ~ { IF scanner.tokenStart>=scanner.inputBuffer.length-10 THEN RefillBuffer[scanner]; scanner.tokenKind _ charconst; scanner.tokenLength _ 2; IF scanner.inputBuffer[scanner.tokenStart+1] = '\\ THEN { IF scanner.inputBuffer[scanner.tokenStart+scanner.tokenLength] IN ['0..'7] THEN { WHILE scanner.inputBuffer[scanner.tokenStart+scanner.tokenLength] IN ['0..'7] DO scanner.tokenLength _ scanner.tokenLength + 1; ENDLOOP; } ELSE scanner.tokenLength _ 3; }; }; GetStringConstant: PROC [scanner: Scanner] ~ { GetC: PROC ~ { IF scanner.tokenStart+scanner.tokenLength>=scanner.inputBuffer.length-10 THEN RefillBuffer[scanner]; scanner.tokenLength _ scanner.tokenLength + 1; IF scanner.inputBuffer[scanner.tokenStart+scanner.tokenLength] = '\\ THEN { scanner.tokenLength _ scanner.tokenLength + 1; IF scanner.inputBuffer[scanner.tokenStart+scanner.tokenLength] IN ['0..'7] THEN { WHILE scanner.inputBuffer[scanner.tokenStart+scanner.tokenLength] IN ['0..'7] DO scanner.tokenLength _ scanner.tokenLength + 1; ENDLOOP; } ELSE scanner.tokenLength _ scanner.tokenLength + 1; }; }; scanner.tokenLength _ 0; GetC[]; UNTIL scanner.inputBuffer[scanner.tokenStart+scanner.tokenLength] = '" DO GetC[]; ENDLOOP; scanner.tokenLength _ scanner.tokenLength + 1; scanner.tokenKind _ string; }; GetComment: PROC [scanner: Scanner] ~ { c: CHAR _ ' ; -- next char after the current end-of-token cc: CHAR _ ' ; -- char after c PeekCC: PROC ~ { IF scanner.tokenStart+scanner.tokenLength+2>=scanner.inputBuffer.length THEN RefillBuffer[scanner]; c _ cc _ '\n; IF scanner.tokenStart+scanner.tokenLength CONTINUE].token; }; FindNewer: PROC [fileName: ROPE, newerThan: BasicTime.GMT] RETURNS [fullName: ROPE _ NIL] ~ { full: ROPE _ NIL; infoProc: FS.InfoProc ~ {IF BasicTime.Period[from: newerThan, to: created] > 0 THEN {fullName _ fullFName; continue _ FALSE}}; FS.EnumerateForInfo[fileName, infoProc]; }; UsingDependenciesCommand: Commander.CommandProc ~ { Reformat: PROC [filename: ROPE] ~ { EndNode: PROC [delta: INTEGER _ 0, format: ATOM _ NIL] = { tc.endOfNode _ TRUE; tc.char _ '\n; tc.format _ format; tc.deltaLevel _ delta; TiogaAccess.Put[writer, tc]; tc.endOfNode _ FALSE; }; PutCharB: Rope.ActionType = { tc.char _ c; TiogaAccess.Put[writer, tc]; }; PutRope: PROC [rope: ROPE] = { [] _ Rope.Map[base: rope, action: PutCharB]; }; PutRopeItalic: PROC [rope: ROPE] = { tc.looks['i] _ TRUE; [] _ Rope.Map[base: rope, action: PutCharB]; tc.looks['i] _ FALSE; }; PutRopeBold: PROC [rope: ROPE] = { tc.looks['b] _ TRUE; [] _ Rope.Map[base: rope, action: PutCharB]; tc.looks['b] _ FALSE; }; tc: TiogaAccess.TiogaChar _ [ charSet: 0, char: '\n, looks: ALL[FALSE], format: $code, comment: FALSE, endOfNode: FALSE, deltaLevel: 0, propList: NIL ]; nextS: IO.STREAM; in: IO.STREAM; nextRope: ROPE; ropeList, newList: LIST OF ROPE; writer: TiogaAccess.Writer _ TiogaAccess.Create[]; in _ FS.StreamOpen[fileName: filename, accessOptions: $read ! FS.Error => {result _ $Failure; msg _ error.explanation; CONTINUE}]; IF in = NIL THEN RETURN; UNTIL IO.EndOf[in] DO newList _ ropeList _ NIL; nextS _ IO.RIS[IO.GetLineRope[stream: in]]; -- get next rope from input nextRope _ IO.GetTokenRope[nextS, IO.TokenProc].token; -- first token, boldface PutRopeBold[Rope.Concat[nextRope, ":"]]; UNTIL IO.EndOf[nextS] DO ropeList _ CONS[IO.GetTokenRope[nextS, IO.TokenProc ! IO.EndOfStream => CONTINUE;].token, ropeList]; ENDLOOP; IF ropeList#NIL THEN { newList _ DReverse[ropeList]; -- destructive reverse nextRope _ IF newList.rest=NIL THEN newList.first ELSE newList.rest.first; -- initialize in case never do following loop FOR r: LIST OF ROPE _ newList, r.rest UNTIL r.rest=NIL DO -- do all but last rope PutRope[Rope.Concat[" ", r.first]]; nextRope _ r.rest.first; ENDLOOP; IF doImpls THEN PutRopeItalic[Rope.Concat[" ", nextRope]] -- last rope is Implementor, italics ELSE PutRope[Rope.Concat[" ", nextRope]]; -- last rope is not Implementor EndNode[delta: 0, format: $code]; }; ENDLOOP; TiogaAccess.WriteFile[writer, filename]; }; switchChar: CHAR = '-; gets: ROPE _ NIL; outputStream: IO.STREAM _ NIL; symTab: SymTab.Ref _ SymTab.Create[997, TRUE]; scanner: Scanner _ CreateScanner[]; c: IO.STREAM _ IO.RIS[cmd.commandLine]; outputName: ROPE _ GetCmdToken[c]; IF outputName=NIL OR Rope.Equal[outputName, ""] THEN RETURN[$Failure, docRope]; doImpls _ reformat _ FALSE; WHILE Rope.Fetch[base: outputName, index: 0]=switchChar DO FOR index: INT IN [1..Rope.Length[outputName]) DO SELECT Rope.Fetch[base: outputName, index: index] FROM 'i => doImpls _ TRUE; 'f => reformat _ TRUE; ENDCASE; ENDLOOP; outputName _ GetCmdToken[c]; ENDLOOP; gets _ GetCmdToken[c]; IF NOT gets.Equal["_"] THEN RETURN[$Failure, docRope]; outputStream _ FS.StreamOpen[fileName: outputName, accessOptions: $create, keep: 2 ! FS.Error => {result _ $Failure; msg _ error.explanation; CONTINUE}]; IF outputStream = NIL THEN RETURN; FOR stem: ROPE _ GetCmdToken[c], GetCmdToken[c] UNTIL stem.Length = 0 DO pattern: ROPE _ IF Rope.Find[stem, ".bcd", 0, FALSE] < 0 THEN Rope.Concat[stem, ".bcd"] ELSE stem; ForEachFile: PROC [fullFName: ROPE] RETURNS [continue: BOOLEAN _ TRUE] ~ { bcdDate: BasicTime.GMT ~ FS.FileInfo[name: fullFName, remoteCheck: FALSE].created; base: ROPE; cp: FS.ComponentPositions; useName: ROPE _ Rope.Concat[base, ".usingList"]; [fullFName, cp] _ FS.ExpandName[fullFName]; base _ fullFName.Substr[cp.base.start, cp.base.length]; useName _ FindNewer[Rope.Concat[base, ".usingList"], bcdDate]; IF useName=NIL THEN { result _ CommandTool.DoCommand[Rope.Concat["UsingList ", fullFName], cmd]; useName _ Rope.Concat[base, ".usingList"]; } ELSE { cmd.out.PutF["Using old %g\n", IO.rope[useName]]; result _ NIL; }; IF result = $Failure THEN NULL ELSE { stream: IO.STREAM _ NIL; stream _ FS.StreamOpen[useName ! FS.Error => {cmd.out.PutRope[error.explanation]; cmd.out.PutChar['\n]; CONTINUE}]; IF stream # NIL THEN { SetScanner[scanner, stream]; RecordDependencies[scanner, base, cmd, symTab]; stream.Close; }; }; }; IF Rope.Find[pattern, "*"] >= 0 THEN FS.EnumerateForNames[pattern, ForEachFile ! FS.Error => {msg _ error.explanation; result _ $Failure; CONTINUE}] ELSE [] _ ForEachFile[pattern ! FS.Error => {msg _ error.explanation; result _ $Failure; CONTINUE}]; IF result = $Failure THEN RETURN; ENDLOOP; WriteResults[outputStream, symTab, cmd]; outputStream.Close; IF reformat THEN Reformat[outputName]; cmd.out.PutF["%g written.\n", IO.rope[outputName]]; }; reformat: BOOL _ FALSE; doImpls: BOOL _ FALSE; docRope: ROPE ~ "Create listing of procedure-level dependencies from bcds ([switches] _ )\n"; Commander.Register["UsingDependencies", UsingDependenciesCommand, docRope]; END. zUsingDependenciesImpl.mesa Copyright (C) 1984, 1985, Xerox Corporation. All rights reserved. Michael Plass, June 28, 1985 2:58:35 pm PDT Pier, February 6, 1986 2:10:38 pm PST Gets the next token into inputBuffer[tokenStart] .. inputBuffer[tokenLength-1] this Proc calls the Interpreter to evaluate a rope of the form Interface.ProcName. If a rope of the form XXX.ProcName comes back, it is assumed that XXX is the implementor of Interface. Since it is possible to get other things back from the Interpreter, like types or errors, some defaults are returned ( -- or ??) instead of the interpreted result. Destructive. [c: CHAR] RETURNS [quit: BOOL _ FALSE] propList: List.PutAssoc[key: $FromTiogaFile, val: $Yes, aList: NIL] The following code assumes there are lines with one or more ropes per line. The first rope is of the form Interface.ProcName. Succeeding ropes up to the last rope in the line are assumed to be names of Implmentations which use that Interface.ProcName. The last rope is assumed to be the name of the Implementor of the Interface.ProcName. result _ CommandTool.DoCommand[Rope.Concat["ReadIndent ", outputName], cmd]; Κy˜šœ™JšœB™BJšœ+™+Icode™%—J˜šΟk ˜ Jš œœœœœœ˜J˜J˜ Jšœ œ!˜0Jšœ œ ˜Jšœ˜J˜ J˜ Jšœ˜J˜J˜J˜ J˜Jšœ˜J˜—J˜šœœ˜$Jšœ œœZ˜sJšœ˜J˜Jšœœœ˜J˜Jšœ œœ ˜šœ œœ˜Jšœœœ˜Jšœ˜Jšœ œœ˜Jšœœ˜Jšœ œ˜Jšœ ˜Jšœ˜J˜—Jšœœ ˜šΟn œœœ˜2Jšœ œ ˜Jšœœœ˜1Jšœ˜J˜—šž œœœœ˜:Jšœ˜Jšœ˜Jšœ œ˜4Jšœ˜Jšœ˜Jšœ˜Jšœ˜J˜—JšœœO˜Yšžœœœœ ˜)šœ˜ Jšœ œ œœ˜AJš œœœœœ˜5Jšœœœ ˜Jšœœ ˜—Jšœ˜J˜—Jšœ œœœ˜šœ œ˜J˜—šžœœ˜,Jšœ3œ˜PJšœ˜Jšœ˜šœ1œ˜9šœ=œ œ˜Qšœ=œ ˜PJšœ.˜.Jšœ˜—Jšœ˜—Jšœ˜Jšœ˜—Jšœ˜J˜—šžœœ˜.šžœœ˜JšœGœ˜dJšœ.˜.šœCœ˜KJšœ.˜.šœ=œ œ˜Qšœ=œ ˜PJšœ.˜.Jšœ˜—Jšœ˜—Jšœ/˜3Jšœ˜—Jšœ˜—Jšœ˜Jšœ˜šœB˜IJšœ˜Jšœ˜—Jšœ.˜.Jšœ˜Jšœ˜J˜—šž œœ˜'JšœœΟc+˜9JšœœŸœ˜šžœœ˜JšœFœ˜cJ˜ šœC˜IJšœ@˜@—šœE˜KJšœC˜C—Jšœ˜—Jšœ˜Jšœ ˜ šœ œ œ ˜(Jšœ.˜.Jšœ ˜ Jšœ˜—Jšœ œ œ/˜KJšœ˜Jšœ˜J˜—šžœœ˜%JšœN™NJšœœ˜Jšœ<˜šœœœ˜JšœC˜CJšœ˜—Jšœ&˜&JšœQ˜QJšœ˜Jšœ~˜~J˜J˜—šžœœœœœœ œ˜SJšœœ˜Jšœ"œœœ˜8šœœœ˜ Jšœœœœ˜5J˜Jšœ˜—Jšœœ˜ J˜J˜—š ž œœœœ œ˜JJšœœ˜Jšœ"œœœ˜8šœœœ˜)Jšœ%œœœ˜;J˜Jšœ˜—Jšœœ˜ J˜J˜—šžœœœœ˜8Jšœœ˜"Jš œœœœœ˜?Jšœ œ˜;Jšœ)˜/J˜J˜—šžœœœœœœœ˜HJšœk˜qJ˜J˜—šœœœ˜Jšœœ˜ Jšœ˜ Jšœ˜J˜—šœ œ œœ˜*J˜—šœ œ˜'Jšœ=˜=J˜J˜—šžœœœ0˜fšžœœ˜Jšœ˜šœœ œ˜eJšœ˜Jšœ˜—Jšœ˜—Jšœœœ˜,Jšœ ˜ šœœ˜?Jšœ˜Jšœ˜—Jšœœ˜4Jšœ ˜ J•StartOfExpansion[]šœœ.œ˜Yšœ˜šœ˜J˜Jšœ˜Jšœ ˜ šœœ˜Jšœ ˜ Jšœœœ˜7Jšœ ˜ Jšœœ˜7J˜Jšœt˜tJšœ ˜ Jšœ˜—Jšœœœ˜8Jšœ ˜ Jšœœœ˜4Jšœ ˜ šœ˜Jšœ œ˜Jš œœœœœœ˜Jšœ$˜$Jšœ˜šœ˜ Jšœœœ ˜/Jšœ˜—šœœœ˜Jš œœœœœœ˜Jšœ/˜/Jšœ˜—Jšœœ ˜Jšœ ˜ Jšœœ ˜$Jšœœœœ˜9Jšœ˜Jšœ˜—Jšœ ˜ Jšœœ ˜$Jšœœœœ˜9Jšœ˜—Jšœ˜—Jšœ˜J˜J˜—šžœœœœœœœ˜LJš œœœœœ˜ Jš œœœœœ˜ Jšœ#œ˜0Jšœ˜J˜—šž œœ œœ0˜UJš œœœœœ˜šžœœœœœœœ˜EJš œ œœœœ˜(Jšœœœœ ˜Jšœœ ˜Jšœœ˜Jšœ˜—Jšœ˜Jšœ ˜ š œœœœœœ˜2Jš œœœœœ ˜"Jšœœœœ˜#Jšœ œ˜ Jšœ˜Jšœ˜šœœ˜Jšœ˜Jšœ˜Jš œœœœœ˜0Jšœ˜—Kšœœ*˜9Jšœ˜Jšœ˜—J˜J˜—š žœœœœœ˜9K™έKšœœœ˜Kšœ œœ˜Kšœ7˜7Kš œ œœœœ˜,Kšœ"˜"K–9[base: ROPE, start: INT _ 0, len: INT _ 2147483647]š œ œ1œœVœ˜¦Kšœœœœ ˜7K˜J˜—šžœœœœœœœœœœ˜HJ™ šœœ˜Jšœœœœ˜Jšœ ˜ Jšœ ˜ Jšœ˜Jšœ˜—Jšœ˜J˜—– "cedar" styleš žœœœœœ˜3Jšœ œ œœ ˜.Jš œ œ œ œ œœ˜HJšœ ˜Jšœ˜J˜—šž œœ œœœœœ˜DJšœœœœ˜IJ˜J˜—šž œœ œœœ œœ˜]Jšœœœ˜Jš œ œ œ4œ#œ˜~Jšœ&˜(J˜J˜—šžœ˜3šžœœ œ˜$š žœœ œœœ˜:Kšœœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœœ˜K˜—–* -- [c: CHAR] RETURNS [quit: BOOL _ FALSE]šΟbœ˜KšΠck&™&Kšœ ˜ Kšœ˜K˜—šžœœœ˜K–T[base: ROPE, start: INT _ 0, len: INT _ 2147483647, action: Rope.ActionType]šœ,˜,K˜—šž œœœ˜$Kšœœ˜K–T[base: ROPE, start: INT _ 0, len: INT _ 2147483647, action: Rope.ActionType]šœ,˜,Kšœœ˜K˜—šž œœœ˜"Kšœœ˜K–T[base: ROPE, start: INT _ 0, len: INT _ 2147483647, action: Rope.ActionType]šœ,˜,Kšœœ˜K˜—šœ˜Kšœ ˜ Kšœ ˜ Kšœœœ˜Kšœ˜Kšœ œ˜Kšœ œ˜Kšœ˜Kšœ?œ™CKšœ ˜ K˜—Kšœœœ˜Kšœœœ˜Kšœ œ˜Kšœ œ˜ Kšœ2˜2Kšœœ7œ7œ˜‚Jšœœœœ˜J™Ρšœœ ˜J–[stream: STREAM]šœœ˜JšœœœœŸ˜GJšœ œœŸ˜OKšœ(˜(šœœœ œœœ œœ˜}Kšœ˜—šœ œœ˜KšœŸ˜4Kš œ œœœœŸ-˜xšœœœœœœœŸ˜QKšœ#˜#K˜Kšœ˜—Kšœ œ+Ÿ$˜^Kšœ&ŸœŸœŸ ˜IKšœ!˜!K˜—Kšœ˜—Kšœ(˜(K˜J˜—Jšœ œ˜Jšœœœ˜Jšœœœœ˜Jšœ(œ˜.J˜#Jš œœœœœ˜'Jšœ œ˜"Jš œ œœœœ˜OK– [base: ROPE, index: INT _ 0]šœœ˜šœ3œ˜;šœœœ˜1šœ,˜6Kšœœ˜Kšœœ˜Kšœ˜—Kšœ˜—Jšœ˜Jšœ˜—Jšœ˜Jšœœœœ˜6JšœœDœ7œ˜™Jšœœœœ˜"šœœ"œ˜HJš œ œœœœœ˜bš ž œœ œœ œœ˜JJšœœœ(œ ˜RJšœœ˜ Jšœœ˜Jšœ œ#˜0Jšœœ˜+Jšœ7˜7Jšœ>˜>šœ œœ˜JšœJ˜JJšœ*˜*Jšœ˜—šœ˜Jšœœ˜1Jšœ œ˜ Jšœ˜—Jšœœ˜šœ˜Jšœœœœ˜Jšœ œœEœ˜sšœ œœ˜Jšœ˜Jšœ/˜/J˜ Jšœ˜—J˜—J˜—Jš œœœ*œ7œ˜”Jšœœ7œ˜dJšœœœ˜!Jšœ˜—Jšœ(˜(Jšœ˜JšœL™LKšœ œ˜&Jšœœ˜3J˜J˜—Kšœ œœ˜Kšœ œœ˜Jšœ œs˜€JšœK˜KJ˜Jšœ˜——…—;:V-