<<>> <> <> <> <> DIRECTORY Commander, CommanderOps, IO, PFS, PFSNames, Rope, SearchPaths; SearchPathCommands: CEDAR PROGRAM IMPORTS Commander, CommanderOps, IO, PFS, PFSNames, Rope, SearchPaths = { ROPE: TYPE ~ Rope.ROPE; SetPathCommand: PROC [cmd: Commander.Handle] RETURNS [result: REF ANY ¬ NIL, msg: ROPE ¬ NIL] ~ { argv: CommanderOps.ArgumentVector ~ CommanderOps.Parse[cmd]; sp: SearchPaths.SearchPath ¬ NIL; IF argv.argc<3 THEN RETURN [$Failure, Rope.Cat["Usage: ", argv[0], " ..."]]; FOR i: INT DECREASING IN [2 .. argv.argc) DO ENABLE PFS.Error => { cmd.err.PutF["PFS.Error[%g, %g] processing %g; path not set.\n", [atom[error.code]], [rope[error.explanation]], [rope[argv[i]]] ]; GOTO Abort}; raw: PFS.PATH ~ PFS.PathFromRope[argv[i]]; abs: PFS.PATH ~ PFS.AbsoluteName[raw]; absdir: PFS.PATH ~ PFSNames.EnsureDirectory[abs]; sp ¬ CONS[absdir, sp]; ENDLOOP; SearchPaths.SetPath[argv[1], sp]; RETURN; EXITS Abort => result ¬ $Failure}; GetPathCommand: PROC [cmd: Commander.Handle] RETURNS [result: REF ANY ¬ NIL, msg: ROPE ¬ NIL] ~ { argv: CommanderOps.ArgumentVector ~ CommanderOps.Parse[cmd]; sp: SearchPaths.SearchPath ¬ NIL; FOR i: INT IN (0..argv.argc) DO sp ¬ SearchPaths.GetPath[argv[i] !PFS.Error => { cmd.err.PutRope[error.explanation]; cmd.err.PutRope[".\n"]; LOOP}]; cmd.out.PutF["SetPath %l%g%l", [rope["b"]], [rope[argv[i]]], [rope["B"]] ]; FOR sp ¬ sp, sp.rest WHILE sp#NIL DO cmd.out.PutF1[" %g", [rope[PFS.RopeFromPath[sp.first]]] ]; ENDLOOP; cmd.out.PutRope["\n"]; ENDLOOP; RETURN}; DeletePathCommand: PROC [cmd: Commander.Handle] RETURNS [result: REF ANY ¬ NIL, msg: ROPE ¬ NIL] ~ { argv: CommanderOps.ArgumentVector ~ CommanderOps.Parse[cmd]; FOR i: INT IN (0..argv.argc) DO had: BOOL ¬ SearchPaths.DeletePath[argv[i]]; cmd.out.PutF1[IF had THEN "Search path %g deleted.\n" ELSE "Search path %g wasn't defined.\n", [rope[argv[i]]] ]; ENDLOOP; RETURN}; InPathCommand: PROC [cmd: Commander.Handle] RETURNS [result: REF ANY ¬ NIL, msg: ROPE ¬ NIL] ~ { argStream: IO.STREAM ~ IO.RIS[cmd.commandLine]; sp, spTail: SearchPaths.SearchPath ¬ NIL; name, subcmd: ROPE; tmp: PFS.PATH; DoSubCmd: PROC ~ { result ¬ CommanderOps.DoCommand[subcmd, cmd]; RETURN}; DO toke: CommanderOps.Token ~ CommanderOps.GetCmdToken[argStream]; IF toke.literal.Length[] = 0 THEN RETURN [$Failure, Rope.Cat["Usage: ", cmd.command, " ... DO cmd"]]; IF toke.literal.Equal["DO"] THEN { IF sp=NIL THEN RETURN [$Failure, Rope.Cat["Usage: ", cmd.command, " ... DO cmd"]]; EXIT}; {ENABLE PFS.Error => { cmd.err.PutF["PFS.Error[%g, %g] processing %g; path not set.\n", [atom[error.code]], [rope[error.explanation]], [rope[toke.value]] ]; GOTO Abort}; raw: PFS.PATH ~ PFS.PathFromRope[toke.value]; abs: PFS.PATH ~ PFS.AbsoluteName[raw]; absdir: PFS.PATH ~ PFSNames.EnsureDirectory[abs]; this: SearchPaths.SearchPath ~ LIST[absdir]; IF spTail=NIL THEN sp ¬ this ELSE spTail.rest ¬ this; spTail ¬ this; }ENDLOOP; name ¬ SearchPaths.GetScratchPath["cmd", sp]; tmp ¬ SearchPaths.ConsSearchDir[name]; subcmd ¬ argStream.GetRope[]; PFS.DoInWDir[tmp, DoSubCmd]; [] ¬ SearchPaths.DeletePath[name]; RETURN; EXITS Abort => result ¬ $Failure}; Commander.Register["SetPath", SetPathCommand, " ... --- defines a search path"]; Commander.Register["GetPath", GetPathCommand, " ... --- reveals the definition(s) of some search path(s)"]; Commander.Register["DeletePath", DeletePathCommand, " ... --- deletes the definition(s) of some search path(s)"]; Commander.Register["InPath", InPathCommand, " ... DO cmd --- executes cmd in a working directory that's a search path constructed from the given directories"]; }.