SearchPathCommands.mesa
Copyright Ó 1992 by Xerox Corporation. All rights reserved.
Last tweaked by Mike Spreitzer May 29, 1992 8:39 am PDT
Interface for the PortableCedar File System; see also PFSBackdoor.mesa.
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], " <path-name> <read/write-dir> <read-dir> <read-dir> ..."]];
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, " <read/write-dir> <read-dir> <read-dir> ... DO cmd"]];
IF toke.literal.Equal["DO"] THEN {
IF sp=NIL THEN RETURN [$Failure, Rope.Cat["Usage: ", cmd.command, " <read/write-dir> <read-dir> <read-dir> ... 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, "<path-name> <read/write-dir> <read-dir> <read-dir> ... --- defines a search path"];
Commander.Register["GetPath", GetPathCommand, "<path-name> ... --- reveals the definition(s) of some search path(s)"];
Commander.Register["DeletePath", DeletePathCommand, "<path-name> ... --- deletes the definition(s) of some search path(s)"];
Commander.Register["InPath", InPathCommand, "<read/write-dir> <read-dir> <read-dir> ... DO cmd --- executes cmd in a working directory that's a search path constructed from the given directories"];
}.