DIRECTORY Commander USING [CommandProc, Register, Handle], CommanderOps USING [ArgumentVector, Parse, Failed], DFInternal USING [AbortDF, GetFileInfo, RemoteFileInfo, ReportFSError], DFUtilities USING [Date, DirectoryItem, FileItem, Filter, IncludeItem, ParseFromStream, ProcessItemProc, RemoveVersionNumber, SyntaxError], FS USING [Error, StreamOpen], IO USING [card, int, Close, GetIndex, rope, STREAM, PutF, PutF1, Put, PutRope], IOClasses USING [CreateDribbleOutputStream], List USING [CompareProc, Sort], Process USING [CheckForAbort], Rope USING [Compare, Concat, Equal, Find, Flatten, Length, ROPE, Run, Substr], SystemNames USING [CedarDir]; DFIncludes: CEDAR PROGRAM IMPORTS Commander, CommanderOps, DFInternal, DFUtilities, FS, IO, IOClasses, List, Process, Rope, SystemNames = { ROPE: TYPE = Rope.ROPE; FileDesc: TYPE = RECORD [ shortName: ROPE, path: ROPE, parent: ROPE -- DF file containing defining occurrence of 'shortName' ]; StripPrefix: PROC [path: ROPE, prefix: ROPE] RETURNS [ROPE] = { len: INT = Rope.Length[prefix]; IF Rope.Run[path, 0, prefix, 0, FALSE] = len THEN RETURN [Rope.Flatten[path, len]]; RETURN [path]; }; Construct: PROC [dfFile, outFile: ROPE, cmd: Commander.Handle] RETURNS [errors, warnings, filesActedUpon: INT ¬ 0] = { logFileStream: IO.STREAM ¬ FS.StreamOpen[fileName: outFile, accessOptions: $create]; log: IO.STREAM ¬ IOClasses.CreateDribbleOutputStream[cmd.out, logFileStream]; listOfFileDescRefs: LIST OF REF ANY ¬ NIL; currentPrefix: ROPE = SystemNames.CedarDir[]; Compare: List.CompareProc = { f1: REF FileDesc = NARROW[ref1]; f2: REF FileDesc = NARROW[ref2]; RETURN[f1.shortName.Compare[f2.shortName, FALSE]]; }; ConstructInner: PROC [dfFile: ROPE, date: DFUtilities.Date, filter: DFUtilities.Filter, nestingDepth: NAT] RETURNS [finished: BOOL ¬ FALSE] = { shortDirectoryPath: ROPE ¬ NIL; shortDfFile: ROPE ¬ StripDfPrefix[dfFile]; StripDfPrefix: PROC [path: ROPE] RETURNS [rest: ROPE] = { RETURN [StripPrefix[StripPrefix[path, currentPrefix], "Top>"]]; }; StripDirPrefix: PROC [path: ROPE] RETURNS [ROPE] = { RETURN [StripPrefix[path, currentPrefix]]; }; DoOneItem: DFUtilities.ProcessItemProc = { Process.CheckForAbort[]; WITH item SELECT FROM directory: REF DFUtilities.DirectoryItem => shortDirectoryPath ¬ StripDirPrefix[directory.path1]; file: REF DFUtilities.FileItem => { desc: REF FileDesc = NEW[FileDesc ¬ [ shortName: DFUtilities.RemoveVersionNumber[file.name], path: shortDirectoryPath, parent: shortDfFile ]]; listOfFileDescRefs ¬ CONS[desc, listOfFileDescRefs]; }; include: REF DFUtilities.IncludeItem => [] ¬ ConstructInner[include.path1, include.date, filter, nestingDepth + 1]; ENDCASE => ERROR; }; dfInfo: REF DFInternal.RemoteFileInfo = NEW[DFInternal.RemoteFileInfo ¬ [name: dfFile, date: date]]; dfStream: IO.STREAM; DFInternal.GetFileInfo[info: dfInfo, client: NIL ! FS.Error => {errors ¬ errors.SUCC; GO TO skip}]; dfStream ¬ FS.StreamOpen[fileName: dfInfo.name ! FS.Error => {errors ¬ errors.SUCC; DFInternal.ReportFSError[error, dfInfo, NIL]; GO TO skip} ]; dfInfo.name ¬ DFUtilities.RemoveVersionNumber[dfInfo.name]; FOR i: NAT IN [1..nestingDepth] DO log.PutRope[" "] ENDLOOP; log.Put[IO.rope["starting to look at "], IO.rope[dfInfo.name], IO.rope["\n"]]; DFUtilities.ParseFromStream[dfStream, DoOneItem, filter ! DFUtilities.SyntaxError -- [reason: ROPE]-- => { errors ¬ errors.SUCC; log.PutF[ "Error: Syntax error in '%g'[%d]: %g\NProcessing of this DF file aborted.", IO.rope[dfInfo.name], IO.card[dfStream.GetIndex[]], IO.rope[reason] ]; CONTINUE }; ABORTED => dfStream.Close[]; ]; dfStream.Close[]; RETURN[TRUE]; EXITS skip => NULL; }; { ENABLE { ABORTED => { errors ¬ errors.SUCC; log.Put[IO.rope["Error: ABORT looking at "], IO.rope[dfFile], IO.rope["\n"]]; }; DFInternal.AbortDF => { errors ¬ errors.SUCC; log.Put[IO.rope["Error: ABORT looking at "], IO.rope[dfFile], IO.rope["\n"]]; CONTINUE }; }; IF ConstructInner[dfFile: dfFile, date: [format: $explicit], filter: [filterA: $source, filterC: $defining], nestingDepth: 0] THEN { PrintFileDesc: PROC [file: REF FileDesc] = { out.PutF["%-30g %-20g %g\n", IO.rope[file.shortName], IO.rope[file.parent], IO.rope[file.path]]; }; fPrev, fCurrent: REF FileDesc ¬ NIL; nFiles: INT ¬ 0; out: IO.STREAM = FS.StreamOpen[fileName: "DFIncludes.txt", accessOptions: $create]; out.PutF1["List of DF file inclusion relationships from %g\n\n", IO.rope[dfFile]]; listOfFileDescRefs ¬ List.Sort[listOfFileDescRefs, Compare]; FOR l: LIST OF REF ANY ¬ listOfFileDescRefs, l.rest UNTIL l = NIL DO { fCurrent ¬ NARROW[l.first]; IF fPrev # NIL AND fPrev.shortName.Equal[fCurrent.shortName, FALSE] THEN { warnings ¬ warnings.SUCC; IF fPrev.parent.Equal[s2: fCurrent.parent, case: FALSE] THEN { log.PutF[ "warning: '%g' appears more than once (via '%g')\n", IO.rope[fPrev.shortName], IO.rope[fPrev.parent] ]; GOTO next; } ELSE log.PutF[ "WARNING: '%g' appears more than once (via '%g' and '%g')\n", IO.rope[fPrev.shortName], IO.rope[fPrev.parent], IO.rope[fCurrent.parent] ]; }; PrintFileDesc[fCurrent]; nFiles ¬ nFiles.SUCC; GOTO next; EXITS next => fPrev ¬ fCurrent } ENDLOOP; out.PutF["\nEND of list of DF file inclusion relationships from %g\n%g files listed\n", IO.rope[dfFile], IO.int[nFiles]]; out.Close[]; log.PutF1["\n***DF file inclusion relationships from %g written onto DFIncludes.txt", IO.rope[dfFile]]; IF errors # 0 OR warnings # 0 THEN { log.PutF["\n*** %g errors and %g warnings written onto DFIncludes.log\n", IO.int[errors], IO.int[warnings]]; } ELSE log.PutRope[".\n"]; }; -- end IF ConstructInner[dfFile, [format: $explicit], [], 0] THEN }; -- ENABLE logFileStream.Close[]; }; DoDFIncludes: Commander.CommandProc = { dfFileName: ROPE ¬ NIL; length: NAT; argv: CommanderOps.ArgumentVector ¬ NIL; outFile: ROPE; argv ¬ CommanderOps.Parse[cmd ! CommanderOps.Failed => { msg ¬ errorMsg; CONTINUE; }]; IF argv = NIL THEN RETURN[$Failure, msg]; IF argv.argc > 3 THEN RETURN[$Failure, "Usage: Dependencies dfFileName {outFile}\n"]; dfFileName ¬ argv[1]; length ¬ dfFileName.Length[]; IF length < 4 OR (Rope.Compare[Rope.Substr[dfFileName, length - 3, 3], ".df", FALSE] # equal AND Rope.Find[dfFileName, "!", MAX[0, length-5]] = -1) THEN dfFileName ¬ Rope.Concat[dfFileName, ".df"]; IF argv.argc = 2 THEN outFile ¬ "DFIncludes.log" ELSE outFile ¬ argv[2]; [] ¬ Construct[dfFileName, outFile, cmd]; }; Commander.Register[ "DFIncludes", DoDFIncludes, "Build a list of df file inclusion relationships from a df file." ]; }. R DFIncludes.mesa Copyright Σ 1985, 1987, 1992 by Xerox Corporation. All rights reserved. derived from Dependencies.mesa Paul Rovner on December 3, 1983 12:52 pm MBrown on December 17, 1983 4:15 pm Russ Atkinson on March 11, 1985 9:16:55 pm PST Doug Wyatt, January 30, 1987 6:04:10 pm PST Willie-s, January 22, 1992 6:46 pm PST PROC[ref1: REF ANY, ref2: REF ANY] RETURNS [Comparison]; START Construct HERE We would like to RESUME at this point, but until ABORTED is redeclared as a SIGNAL, it won't work. The following is a terrible cheat, since the date is technically illegal. However, the (desired!) effect is to treat a version number on 'dfFile' as truth (i.e., it won't be stripped off by DFInternal.GetFileInfo.) The list of FileDesc has now been filled. PROC [cmd: Commander.Handle] RETURNS [result: REF _ NIL, msg: Rope.ROPE _ NIL] Κe–(cedarcode) style•NewlineDelimiter ™codešœ™Kšœ Οeœ=™HKšœ™Kšœ(™(Kšœ#™#Kšœ.™.K™+K™&K™—šΟk ˜ Kšœ žœ!˜0Kšœ žœ!˜3Kšœ žœ7˜GKšœ žœz˜‹Kšžœžœ˜Kšžœžœ$žœ˜OKšœ žœ˜,Kšœžœ˜Kšœžœ˜Kšœžœ1žœ˜NKšœ žœ ˜K˜—šΟb œžœž˜Kšžœ3žœžœ1˜qK˜Kšžœžœžœ˜šœ žœžœ˜Kšœ žœ˜Kšœžœ˜ KšœžœΟc8˜FK˜—K˜—š Οn œžœžœ žœžœžœ˜?Kšœžœ˜Kšžœžœžœžœ˜SKšžœ˜K˜K˜—š ‘ œžœžœœžœ$žœ ˜vKšœžœžœžœ7˜TKšœžœžœ?˜MKš œžœžœžœžœžœ˜*Kšœžœ˜-šŸœ˜Kš žœžœžœžœžœžœ™8Kšœžœ žœ˜ Kšœžœ žœ˜ Kšžœ$žœ˜2Kšœ˜—š‘œžœ žœDžœžœ žœžœ˜Kšœžœžœ˜Kšœ žœ˜*š Πbn œžœžœžœžœ˜9Kšžœ9˜?Kšœ˜—š ’œžœžœžœžœ˜4Kšžœ$˜*Kšœ˜—šŸ œ!˜*Kšœ˜šžœžœžœ˜šœ žœ˜+K˜5—šœžœ˜#šœžœ žœ ˜%Kšœ6˜6Kšœ˜Kšœ˜K˜—Kšœžœ˜4K˜—šœ žœ˜'K˜K—Kšžœžœ˜—Kšœ˜—Kšœžœžœ9˜dKšœ žœžœ˜Kš œ-žœžœžœžœžœ˜cšœ žœ!˜.Kš œžœžœ*žœžœžœ˜^K˜—K˜;Kš žœžœžœžœžœ˜=Kšœžœžœžœ ˜Nšœ9˜9šœ œ˜0Kšœžœ˜šœ ˜ šœK˜KKšžœžœžœ ˜C—Kšœ˜—Kšž˜K˜—Kšžœ˜Kšœ˜—K˜Kšžœžœ˜ Kšžœ žœ˜Kšœ˜—K˜K™K˜šœ˜šžœ˜šžœ˜ Kšœžœ˜Kšœžœ#žœžœ ˜MKšœžœžœžœ™bKšœ˜—šœ˜Kšœžœ˜Kšœžœ#žœžœ ˜MKšž˜Kšœ˜—Kšœ˜—KšœΧ™Χšžœ|žœ˜„Kšœ)™)š’ œžœžœ˜,šœ˜Kšžœžœžœ˜C—Kšœ˜—Kšœžœ žœ˜$Kšœžœ˜Kšœžœžœžœ@˜SKšœAžœ˜RK˜<šžœžœžœžœžœžœžœžœ˜FKšœ žœ ˜š žœ žœžœ+žœžœ˜JKšœžœ˜šžœ/žœ˜7šžœ˜šœ ˜ Kšœ4˜4Kšžœžœ˜/K˜—Kšžœ˜ K˜—šž˜šœ ˜ Kšœ=˜=Kšžœžœžœ˜IK˜———K˜—Kšœ˜Kšœžœ˜Kšžœ˜ Kšžœ˜ Kšžœ˜—šœW˜WKšžœžœ˜!—K˜ ˜UKšžœ˜—šžœ žœ ˜šžœ˜šœI˜IKšžœžœ˜"—Kšœ˜—Kšžœ˜—Kšœ A˜E—Kšœ  ˜ —Kšœ˜Kšœ˜K˜—š‘ œ˜'Kš žœžœ žœžœ žœžœ™NKšœ žœžœ˜Kšœžœ˜ Kšœ$žœ˜(Kšœ žœ˜K˜KšœJžœ˜WKšžœžœžœžœ˜)Kšžœžœžœ9˜UK˜K˜K˜š žœ žœ>žœ žžœžœ˜“Kšžœ-˜1—Kšžœžœžœ˜HK˜)Kšœ˜K˜—šœ˜Kšœ]˜]Kšœ˜K˜—Kšœ˜K˜—…—B$ω