<<>> <> <> <> DIRECTORY Atom USING [ MakeAtom ], Commander USING [ Register, CommandProc ], CommanderOps USING [ GetProp, NextArgument ], IO, LoganBerry USING [ Error, LogInfo, IndexInfo, SchemaInfo, Describe, nullDB, OpenDB, Open ], Rope USING [ Concat, Equal, Fetch, Find, Length, ROPE, Substr ], PFS USING [ ErrorGroup, Error, PATH, PathFromRope, FileInfo, RopeFromPath, StreamOpen ], PFSNames USING [ ComponentRope, Directory, ShortName ], SymTab USING [ Create, Erase, Fetch, Ref, Store ], UserProfile USING [ Token ], WalnutOps USING [ ValidOpsHandle ], WalnutWindow USING [ WalnutHandle, GetHandleList, Shutdown, StartUp ] ; WalnutUtilsImpl: CEDAR PROGRAM IMPORTS Atom, Commander, CommanderOps, IO, LoganBerry, Rope, PFS, PFSNames, SymTab, UserProfile, WalnutWindow, WalnutOps ~ { OPEN IO; ROPE: TYPE ~ Rope.ROPE; WalnutFileInfo: TYPE ~ REF WalnutFileInfoBody; WalnutFileInfoBody: TYPE ~ RECORD [ rootFileName: ROPE, logFileName: ROPE, dbName: ROPE, lbLogFileName: ROPE, indexNames: LIST OF IndexInfo ]; IndexInfo: TYPE ~ REF IndexInfoBody; IndexInfoBody: TYPE ~ RECORD [ key: ATOM, fileName: ROPE ]; wfis: SymTab.Ref; FileExists: PROC[name: Rope.ROPE] RETURNS [exists: BOOL¬TRUE] ~ { gotName: BOOL¬FALSE; [] ¬ PFS.FileInfo[name: PFS.PathFromRope[name]! PFS.Error => IF error.group=$user AND error.code=$unknownFile THEN { exists¬FALSE; CONTINUE}]; }; GetTwiddleFile: PROC[name: Rope.ROPE] RETURNS [baseExists: BOOL¬TRUE, twiddleName: Rope.ROPE] ~ { IF ~FileExists[name] THEN RETURN[FALSE, NIL]; twiddleName ¬ name; WHILE TRUE DO twiddleName ¬ twiddleName.Concat["~"]; IF ~FileExists[twiddleName] THEN RETURN; ENDLOOP; }; FindTemp: Commander.CommandProc ~ { baseExists: BOOL; res: Rope.ROPE; base: Rope.ROPE; [baseExists, res] ¬ GetTwiddleFile[CommanderOps.NextArgument[cmd]]; IF baseExists THEN { result ¬ res; IO.PutRope[cmd.out, res]; } ELSE { result ¬ $Failure; msg ¬ "No such file" } }; Wait: Commander.CommandProc ~ { [] ¬ WalnutOps.ValidOpsHandle[NIL]; }; CloseAll: Commander.CommandProc ~ { hl: LIST OF WalnutWindow.WalnutHandle ¬ WalnutWindow.GetHandleList[]; FOR l: LIST OF WalnutWindow.WalnutHandle ¬ hl, l.rest WHILE l#NIL DO WalnutWindow.Shutdown[l.first]; ENDLOOP; }; DirectoryOf: Commander.CommandProc ~ { fileName: Rope.ROPE ¬ CommanderOps.NextArgument[cmd]; filePath: PFS.PATH ¬ PFS.FileInfo[PFS.PathFromRope[fileName]].fullFName; IO.PutRope[cmd.out, PFS.RopeFromPath[PFSNames.Directory[filePath]]]; }; DirectoryIfGiven: Commander.CommandProc ~ { fileName: Rope.ROPE ¬ CommanderOps.NextArgument[cmd]; filePath: PFS.PATH ¬ PFS.PathFromRope[fileName]; fileName ¬ PFS.RopeFromPath[PFSNames.Directory[filePath]]; IF fileName = NIL OR fileName.Length[] = 0 THEN fileName ¬ "./"; IO.PutRope[cmd.out, fileName]; }; DefaultDirectory: Commander.CommandProc ~ { fileName: Rope.ROPE ¬ CommanderOps.NextArgument[cmd]; filePath: PFS.PATH; defaultDirectory: Rope.ROPE ¬ CommanderOps.NextArgument[cmd]; IF fileName=NIL OR defaultDirectory=NIL THEN RETURN[$Failure, "Usage: DefaultDirectory "]; filePath ¬ PFS.PathFromRope[fileName]; fileName ¬ PFS.RopeFromPath[PFSNames.Directory[filePath]]; IF fileName = NIL OR fileName.Length[] = 0 THEN fileName ¬ defaultDirectory; IO.PutRope[cmd.out, fileName]; }; ShortNameOf: Commander.CommandProc ~ { filePath: PFS.PATH ¬ PFS.PathFromRope[CommanderOps.NextArgument[cmd]]; shortName: Rope.ROPE ¬ PFSNames.ComponentRope[PFSNames.ShortName[filePath]]; IO.PutRope[cmd.out, shortName]; }; DefaultExtension: Commander.CommandProc ~ { fileName: Rope.ROPE ¬ CommanderOps.NextArgument[cmd]; defaultExtension: Rope.ROPE ¬ CommanderOps.NextArgument[cmd]; index: INT; IF fileName=NIL OR defaultExtension=NIL THEN RETURN[$Failure, "Usage: DefaultExtension "]; index ¬ Rope.Find[fileName, "."]; IF index=-1 THEN fileName ¬ IO.PutFR["%g.%g", rope[fileName], rope[defaultExtension]] ELSE IF index=fileName.Length[]-1 THEN fileName ¬ fileName.Concat[defaultExtension]; IO.PutRope[cmd.out, fileName]; }; BaseName: Commander.CommandProc ~ { index: INT; shortName: Rope.ROPE; filePath: PFS.PATH; fileName: Rope.ROPE ¬ CommanderOps.NextArgument[cmd]; IF fileName=NIL THEN RETURN[$Failure, "Usage: BaseName "]; filePath ¬ PFS.PathFromRope[fileName]; shortName ¬ PFSNames.ComponentRope[PFSNames.ShortName[filePath]]; index ¬ Rope.Find[shortName, "."]; IF index#-1 THEN shortName ¬ shortName.Substr[len: index]; IO.PutRope[cmd.out, shortName]; }; ScriptDefault: Commander.CommandProc ~ { default: Rope.ROPE ¬ CommanderOps.NextArgument[cmd]; userSupplied: Rope.ROPE ¬ CommanderOps.NextArgument[cmd]; IF userSupplied=NIL OR userSupplied.Length[]=0 OR userSupplied.Equal["."] OR userSupplied.Fetch[0] = '$ THEN userSupplied ¬ default; IO.PutRope[cmd.out, userSupplied]; }; MakeEmptyLBLog: Commander.CommandProc ~ { fileName: Rope.ROPE ¬ CommanderOps.NextArgument[cmd]; s: IO.STREAM; IF fileName=NIL THEN RETURN[$Failure, "Usage: MakeEmptyLBLog "]; s ¬ PFS.StreamOpen[PFS.PathFromRope[fileName], $create]; s.PutChar['\377]; s.Close[]; }; WalnutFile: Commander.CommandProc ~ TRUSTED { spec: Rope.ROPE; resultFile: Rope.ROPE; rootRqst: BOOL; wfi: WalnutFileInfo; rootFileName: Rope.ROPE ¬ CommanderOps.NextArgument[cmd]; IF rootFileName.Equal["."] OR rootFileName=NIL THEN rootFileName ¬ UserProfile.Token["Walnut.WalnutRootFile"]; IF rootFileName=NIL THEN { result¬$Failure; msg ¬ "no root file name"; RETURN; }; spec ¬ CommanderOps.NextArgument[cmd]; IF spec=NIL THEN spec ¬ "rootFile"; rootRqst ¬ spec.Equal["rootFile", FALSE]; IF spec.Equal["clear", FALSE] THEN { IF wfis#NIL THEN SymTab.Erase[wfis]; msg ¬ "Walnut Info Cleared"; RETURN; }; IF ~rootRqst THEN wfi ¬ GetWFI[rootFileName]; IF ~rootRqst AND wfi=NIL THEN { result ¬ $Failure; msg ¬ "Walnut db file information not available; check root file and ancillary LoganBerry databases."; RETURN; }; SELECT TRUE FROM rootRqst => resultFile ¬ rootFileName; spec.Equal["lblog", FALSE]=> resultFile ¬ wfi.lbLogFileName; spec.Equal["db", FALSE]=> resultFile ¬ wfi.dbName; spec.Equal["log", FALSE]=> resultFile ¬ wfi.logFileName; spec.Equal["index", FALSE]=> { indexKey: ATOM ¬ Atom.MakeAtom[CommanderOps.NextArgument[cmd]]; IF indexKey=NIL THEN { result ¬ $Failure; msg ¬ usage; }; FOR iList: LIST OF IndexInfo ¬ wfi.indexNames, iList.rest WHILE iList#NIL DO IF iList.first.key#indexKey THEN LOOP; resultFile ¬ iList.first.fileName; EXIT; ENDLOOP; }; ENDCASE => { result ¬ $Failure; msg ¬ usage; }; IF resultFile=NIL THEN { result ¬ $Failure; RETURN; }; <> IO.PutRope[cmd.out, resultFile]; }; GetWFI: PROC[rootFileName: ROPE] RETURNS [wfi: WalnutFileInfo] ~ TRUSTED { s: IO.STREAM; IF wfis=NIL THEN wfis ¬ SymTab.Create[case: TRUE]; wfi ¬ NARROW[SymTab.Fetch[wfis, rootFileName].val]; IF wfi#NIL THEN RETURN; wfi ¬ NEW[WalnutFileInfoBody]; wfi.rootFileName ¬ rootFileName; s ¬ PFS.StreamOpen[PFS.PathFromRope[rootFileName]]; WHILE ~s.EndOf[] DO lineBuf: REF TEXT; key: ROPE; lineBuf ¬ s.GetLine[lineBuf]; key ¬ LOOPHOLE[lineBuf]; SELECT TRUE FROM key.Equal["Database", FALSE] => { db: LoganBerry.OpenDB ¬ LoganBerry.nullDB; si: LoganBerry.SchemaInfo; wfi.dbName ¬ s.GetLineRope[]; db ¬ LoganBerry.Open[dbName: wfi.dbName!LoganBerry.Error => CONTINUE]; IF db#LoganBerry.nullDB THEN { si ¬ LoganBerry.Describe[db: db]; wfi.lbLogFileName ¬ si.logs.first.file; FOR ii: LIST OF LoganBerry.IndexInfo ¬ si.indices, ii.rest WHILE ii#NIL DO iInfo: IndexInfo ¬ NEW[IndexInfoBody ¬ [ii.first.key, ii.first.file]]; wfi.indexNames ¬ CONS[iInfo, wfi.indexNames]; ENDLOOP; }; }; key.Equal["LogInfo", FALSE] => { logFileName: ROPE ¬ s.GetLineRope[]; lineBuf ¬ s.GetLine[lineBuf]; lineBuf ¬ s.GetLine[lineBuf]; key ¬ LOOPHOLE[lineBuf]; IF key.Fetch[0] = '0 THEN wfi.logFileName ¬ logFileName; }; ENDCASE; ENDLOOP; IF wfi.dbName=NIL OR wfi.logFileName=NIL THEN RETURN[NIL]; [] ¬ wfis.Store[rootFileName, wfi]; }; StartWalnutReadOnly: Commander.CommandProc ~ { <> rootFileName: Rope.ROPE ¬ CommanderOps.NextArgument[cmd]; []¬WalnutWindow.StartUp[rootFileName, TRUE]; }; IFFailed: Commander.CommandProc ~ { result ¬ CommanderOps.GetProp[cmd, $Result]; IF result = $Failure THEN result ¬ NIL ELSE result ¬ $Failure; }; usage: Rope.ROPE ¬ "Usage: WalnutFile etc. etc. etc."; Commander.Register["Waitt", Wait, "Wait for scavenge or whatever to finish."]; Commander.Register["CloseAll", CloseAll, "Close all Walnut windows."]; <> Commander.Register["FindTemp", FindTemp, "Find unused temp file name by appending ~'s to base file name."]; Commander.Register["MakeEmptyLBLog", MakeEmptyLBLog, "Create empty log file (with valid termination character in it) Usage: MakeEmptyLBLog "]; Commander.Register["WalnutFile", WalnutFile, "Obtain specified Walnut implementation file Usage: WalnutFile etc. etc. etc."]; <> <<>> Commander.Register["BaseName", BaseName, "/a/b/c/d/e/f.g => f"]; Commander.Register["DefaultExtension", DefaultExtension, "Produce file name given file name and default extension, using default extension if none was supplied."]; Commander.Register["DefaultDirectory", DefaultDirectory, "Produce directory name given file name and default directory, using default directory if none was supplied."]; Commander.Register["DirectoryOf", DirectoryOf, "Produce prefix given path name"]; Commander.Register["DirectoryIfGiven", DirectoryIfGiven, "Produce prefix, if any, given path name"]; Commander.Register["ShortNameOf", ShortNameOf, "Produce short file name given path name"]; Commander.Register["ScriptDefault", ScriptDefault, "ScriptDefault ; provide the value if the user- value is in one way or another null"]; <> Commander.Register["IFFailed", IFFailed, "Fail iff previous command did not."]; }.