DIRECTORY Atom USING [MakeAtom], Basics USING [], BasicTime USING [GMT, Now, nullGMT], Commander USING [CommandProc, Register], CommanderOps USING [ArgumentVector, Failed, Parse], Convert USING [AppendInt], DFUtilities USING [DirectoryItem, FileItem, IncludeItem, ParseFromStream, ProcessItemProc, SyntaxError], IO USING [Close, EndOfStream, GetCedarToken, GetChar, GetIndex, PeekChar, PutChar, PutF1, PutFR, PutFR1, PutRope, SkipWhitespace, STREAM, TokenKind], List USING [Compare, CompareProc, Sort], PFS USING [EnumerateForNames, Error, FileInfo, GetName, NameProc, OpenFileFromStream, PATH, PathFromRope, RopeFromPath, StreamOpen], PFSNames USING [ReplaceShortName, ShortName, ShortNameRope, StripVersionNumber], Process USING [CheckForAbort], RefText USING [InlineAppendChar, TrustTextAsRope], Rope USING [ActionType, Compare, Concat, Equal, Fetch, FindBackward, Flatten, FromRefText, Length, Map, Match, ROPE, SkipOver, SkipTo], SymTab USING [Create, FetchText, Ref, Store], TiogaAccess USING [Create, Put, TiogaChar, WriteFile, Writer]; XRef: CEDAR PROGRAM IMPORTS Atom, BasicTime, Commander, CommanderOps, Convert, DFUtilities, IO, List, PFS, PFSNames, Process, RefText, Rope, SymTab, TiogaAccess = BEGIN ROPE: TYPE = Rope.ROPE; STREAM: TYPE = IO.STREAM; IdEntry: TYPE = RECORD [ name: ROPE, refs: LIST OF IdRef ฌ NIL, reserved: ATOM ฌ NIL]; IdRef: TYPE = RECORD [ fileName: ROPE, -- file name where reference occurs index: INT, -- index where reference occurs defn: BOOL]; -- indicates a defining reference DoCommandProc: Commander.CommandProc = { out: STREAM = cmd.out; switches: PACKED ARRAY CHAR['a..'z] OF BOOL ฌ ALL[FALSE]; ProcessSwitches: PROC [arg: ROPE] = { sense: BOOL ฌ TRUE; FOR index: INT IN [0..Rope.Length[arg]) DO char: CHAR ฌ Rope.Fetch[arg, index]; SELECT char FROM '- => LOOP; '~ => {sense ฌ NOT sense; LOOP}; 'x, 'X => IF filesRead # 0 THEN DumpXref[xrefName]; IN ['a..'z] => switches[char] ฌ sense; IN ['A..'Z] => switches[char + ('a-'A)] ฌ sense; ENDCASE; brief ฌ NOT switches['v]; sense ฌ TRUE; ENDLOOP; }; brief: BOOL ฌ TRUE; EachStream: PROC [stream: STREAM, mesa: BOOL] = { blockLevel: INTEGER ฌ 0; parenLevel: INTEGER ฌ 0; lastId: REF IdEntry ฌ NIL; lastPos: INT ฌ 0; inDirectory: BOOL ฌ FALSE; inType: BOOL ฌ FALSE; AddRef: PROC [newRef: LIST OF IdRef] = { tail: LIST OF IdRef ฌ lastId.refs; IF tail = NIL THEN { idList ฌ CONS[lastId, idList]; newRef.rest ฌ newRef; uniqueTokensRead ฌ uniqueTokensRead + 1; } ELSE { newRef.rest ฌ tail.rest; tail.rest ฌ newRef; }; tokensRead ฌ tokensRead + 1; lastId.refs ฌ newRef; }; curFileName: ROPE ฌ PFS.RopeFromPath[PFS.GetName[PFS.OpenFileFromStream[stream]].fullFName]; IF NOT switches['f] THEN curFileName ฌ GetShortName[curFileName]; ReportName[curFileName]; filesRead ฌ filesRead + 1; IF fileListTail = NIL THEN fileListTail ฌ fileListHead ฌ LIST[curFileName] ELSE fileListTail ฌ (fileListTail.rest ฌ LIST[curFileName]); IF symTab = NIL THEN InitTable[]; IF switches['t] THEN { start: INT; DO c: CHAR ฌ IO.GetChar[stream ! IO.EndOfStream => EXIT]; SELECT c FROM IN ['a..'z], IN ['A..'Z] => {}; ENDCASE => LOOP; cToken[0] ฌ c; cToken.length ฌ 1; start ฌ IO.GetIndex[stream] - 1; DO c: CHAR ฌ IO.GetChar[stream ! IO.EndOfStream => EXIT]; SELECT c FROM IN ['a..'z], IN ['A..'Z], IN ['0..'9], '' => cToken ฌ RefText.InlineAppendChar[cToken, c]; ENDCASE => EXIT; ENDLOOP; WITH SymTab.FetchText[symTab, cToken].val SELECT FROM id: REF IdEntry => lastId ฌ id; ENDCASE => { new: REF IdEntry ฌ NEW[IdEntry ฌ [name: Rope.FromRefText[cToken]]]; [] ฌ SymTab.Store[symTab, new.name, new]; lastId ฌ new; }; AddRef[LIST[[curFileName, start, FALSE]]]; ENDLOOP; } ELSE { DO tokenKind: IO.TokenKind; Process.CheckForAbort[]; [token: cToken, tokenKind: tokenKind] ฌ IO.GetCedarToken[stream, cToken]; SELECT tokenKind FROM tokenSINGLE => { SELECT cToken[0] FROM '[, '( => parenLevel ฌ parenLevel + 1; '], ') => parenLevel ฌ parenLevel - 1; '{ => IF NOT inType THEN blockLevel ฌ blockLevel + 1; '} => IF NOT inType THEN { c: CHAR ฌ '.; c ฌ IO.PeekChar[stream ! IO.EndOfStream => CONTINUE]; blockLevel ฌ blockLevel - 1; IF blockLevel <= 0 OR c = '. THEN EXIT; }; ', => LOOP; '; => GO TO clearFlags; ENDCASE; EXITS clearFlags => inDirectory ฌ inType ฌ FALSE; }; tokenID => { WITH SymTab.FetchText[symTab, cToken].val SELECT FROM id: REF IdEntry => { SELECT id.reserved FROM NIL => { lastId ฌ id; GO TO addReference; }; $BEGIN => blockLevel ฌ blockLevel + 1; $END => { c: CHAR ฌ '.; c ฌ IO.PeekChar[stream ! IO.EndOfStream => CONTINUE]; blockLevel ฌ blockLevel - 1; IF blockLevel <= 0 OR c = '. THEN EXIT; }; $DIRECTORY => {inDirectory ฌ TRUE; GO TO retainDirectoryFlag}; $USING => GO TO retainDirectoryFlag; $TYPE => {inType ฌ TRUE; GO TO retainDirectoryFlag}; ENDCASE; inDirectory ฌ FALSE; EXITS retainDirectoryFlag => {}; }; ENDCASE => { new: REF IdEntry ฌ NEW[IdEntry ฌ [name: Rope.FromRefText[cToken]]]; [] ฌ SymTab.Store[symTab, new.name, new]; lastId ฌ new; GO TO addReference; }; EXITS addReference => { ENABLE IO.EndOfStream => LOOP; index: INT ฌ IO.GetIndex[stream]-cToken.length; defn: BOOL ฌ FALSE; c: CHAR ฌ 0C; [] ฌ IO.SkipWhitespace[stream ! IO.EndOfStream => CONTINUE]; c ฌ IO.PeekChar[stream ! IO.EndOfStream => CONTINUE]; IF c = ': THEN IF parenLevel = 0 AND blockLevel > 0 THEN defn ฌ TRUE; AddRef[LIST[[curFileName, index, defn]]]; LOOP; }; }; tokenERROR => EXIT; tokenEOF => EXIT; ENDCASE; lastId ฌ NIL; ENDLOOP; }; IO.Close[stream]; }; InitTable: PROC = { reserved: ROPE ฌ "RECORD POINTER REF VAR LIST ARRAY SEQUENCE DESCRIPTOR PROCEDURE PROC PORT SIGNAL ERROR PROCESS PROGRAM MONITOR DEFINITIONS ZONE RELATIVE LONG TYPE FRAME TO ORDERED UNCOUNTED PAINTED BASE OF PACKED RETURNS SAFE UNSAFE MONITORED OVERLAID COMPUTED MACHINE DEPENDENT DIRECTORY IMPORTS EXPORTS SHARES LOCKS USING PUBLIC PRIVATE CEDAR CHECKED TRUSTED UNCHECKED ENTRY INTERNAL INLINE READONLY CODE ABS ALL AND APPLY CONS MAX MIN MOD NOT OR ORD PRED LENGTH NEW START SUCC VAL FORK JOIN LOOPHOLE NARROW ISTYPE SIZE FIRST LAST NIL TRASH NULL IF THEN ELSE WITH FROM FOR DECREASING IN THROUGH UNTIL WHILE REPEAT FINISHED RETURN EXIT LOOP GOTO GO FREE WAIT RESTART NOTIFY BROADCAST STOP RESUME REJECT CONTINUE RETRY TRANSFER STATE OPEN ENABLE ANY EXITS END ENDLOOP ENDCASE BEGIN DO SELECT "; builtIn: ROPE ฌ "TRUE FALSE INT CARD INTEGER CARDINAL BOOL BOOLEAN UNSPECIFIED CHARACTER CHAR WORD REAL NAT TEXT STRING MONITORLOCK CONDITION MDSZone StringBody ATOM UNWIND ABORTED "; symTab ฌ SymTab.Create[1253]; AddReserved[symTab, reserved]; AddReserved[symTab, builtIn]; }; ReportName: PROC [name: ROPE] = { THROUGH [0..indent) DO IO.PutChar[out, ' ]; ENDLOOP; IO.PutF1[out, " reading %g\n", [rope[name]]]; }; DumpXref: PROC [arg: ROPE] = { tc: TiogaAccess.TiogaChar ฌ [ charSet: 0, char: '\n, looks: ALL[FALSE], format: NIL, comment: FALSE, endOfNode: TRUE, deltaLevel: 1, propList: NIL ]; PutRope: PROC [rope: ROPE] = { [] ฌ Rope.Map[base: rope, action: PutCharB]; }; PutRopeBold: PROC [rope: ROPE] = { tc.looks['n] ฌ TRUE; [] ฌ Rope.Map[base: rope, action: PutCharB]; tc.looks['n] ฌ FALSE; }; PutRopeItalic: PROC [rope: ROPE] = { tc.looks['c] ฌ TRUE; [] ฌ Rope.Map[base: rope, action: PutCharB]; tc.looks['c] ฌ FALSE; }; PutCharB: Rope.ActionType = { IF brief THEN {IO.PutChar[st, c]; RETURN}; tc.char ฌ c; TiogaAccess.Put[writer, tc]; }; PutChar: PROC [c: CHAR] = { IF brief THEN {IO.PutChar[st, c]; RETURN}; tc.char ฌ c; TiogaAccess.Put[writer, tc]; }; EndNode: PROC [delta: INTEGER ฌ 0, format: ATOM ฌ NIL] = { IF brief THEN {IO.PutChar[st, '\n]; RETURN}; tc.endOfNode ฌ TRUE; tc.char ฌ '\n; tc.format ฌ format; tc.deltaLevel ฌ delta; TiogaAccess.Put[writer, tc]; tc.endOfNode ฌ FALSE; }; writer: TiogaAccess.Writer ฌ IF brief THEN NIL ELSE TiogaAccess.Create[]; st: IO.STREAM ฌ IF brief THEN PFS.StreamOpen[PFS.PathFromRope[arg], $create] ELSE NIL; buffer: REF TEXT ฌ NEW[TEXT[12]]; IF filesRead = 1 THEN IO.PutRope[out, " 1 file read\n"] ELSE IO.PutF1[out, " %g files read\n", [integer[filesRead]] ]; IF NOT brief THEN TiogaAccess.Put[writer, tc]; tc.comment ฌ TRUE; tc.endOfNode ฌ FALSE; tc.propList ฌ NIL; IO.PutF1[out, " xref output to %g\n", [rope[arg]]]; PutRope[arg]; EndNode[1]; PutRope[IO.PutFR1["taken on %g", [time[BasicTime.Now[]]]]]; IF NOT brief THEN EndNode[0]; PutRope[IO.PutFR["# files: %g, # tokens: %g, # unique tokens: %g", [integer[filesRead]], [integer[tokensRead]], [integer[uniqueTokensRead]] ]]; EndNode[1]; FOR each: LIST OF ROPE ฌ fileListHead, each.rest WHILE each # NIL DO PutRope[each.first]; EndNode[0]; ENDLOOP; EndNode[-2]; tc.comment ฌ FALSE; idList ฌ List.Sort[idList, MySort]; IF switches['d] THEN { anyOut: BOOL ฌ FALSE; FOR each: LIST OF REF ANY ฌ idList, each.rest WHILE each # NIL DO WITH each.first SELECT FROM idEntry: REF IdEntry => { init: LIST OF IdRef = idEntry.refs; refs: LIST OF IdRef ฌ init; IF refs # NIL THEN { WHILE refs # NIL DO IF NOT refs.first.defn THEN GO TO noteUsage; refs ฌ refs.rest; IF refs = init THEN EXIT; ENDLOOP; IF NOT anyOut THEN { PutRope["Warning! The following names were defined by not otherwise used: "]; anyOut ฌ TRUE; }; PutRope[idEntry.name]; PutChar[' ]; EXITS noteUsage => {}; }; }; ENDCASE; ENDLOOP; IF anyOut THEN {EndNode[0]; EndNode[0]}; }; SELECT TRUE FROM brief => { WHILE idList # NIL DO each: REF IdEntry = NARROW[idList.first]; init: LIST OF IdRef = each.refs; refs: LIST OF IdRef ฌ init; IF refs # NIL THEN { refs ฌ refs.rest; init.rest ฌ NIL; each.refs ฌ NIL; IO.PutF1[st, "\n%g:", [rope[each.name]]]; WHILE refs # NIL DO fileName: ROPE = refs.first.fileName; rest: LIST OF IdRef ฌ refs.rest; defn: BOOL ฌ refs.first.defn; refs.rest ฌ NIL; IO.PutF1[st, " %g", [rope[fileName]]]; WHILE rest # NIL AND rest.first.fileName = fileName DO nrest: LIST OF IdRef ฌ rest.rest; IF rest.first.defn THEN defn ฌ TRUE; rest.rest ฌ NIL; rest ฌ nrest; ENDLOOP; IF defn THEN IO.PutChar[st, '!]; refs ฌ rest; ENDLOOP; IO.PutRope[st, "\n"]; }; idList ฌ idList.rest; ENDLOOP; IO.Close[st]; }; ENDCASE => { WHILE idList # NIL DO each: REF IdEntry ฌ NARROW[idList.first]; tail: LIST OF IdRef ฌ each.refs; IF tail # NIL THEN { refs: LIST OF IdRef ฌ tail.rest; fileName: ROPE ฌ NIL; tail.rest ฌ NIL; each.refs ฌ NIL; PutRopeBold[each.name]; PutRopeBold[":"]; IF filesRead > 1 THEN EndNode[1, $code]; WHILE refs # NIL DO index: INT = refs.first.index; tail ฌ refs.rest; IF filesRead > 1 AND refs.first.fileName # fileName THEN { IF fileName # NIL THEN EndNode[0, $code]; fileName ฌ refs.first.fileName; PutRopeItalic[fileName]; PutChar[' ]; }; buffer.length ฌ 0; [] ฌ Convert.AppendInt[buffer, ABS[index], 10, FALSE]; PutChar[' ]; IF refs.first.defn THEN PutRopeBold[RefText.TrustTextAsRope[buffer]] ELSE PutRope[RefText.TrustTextAsRope[buffer]]; refs.rest ฌ NIL; refs ฌ tail; ENDLOOP; EndNode[IF filesRead > 1 THEN -1 ELSE 0, $code]; }; idList ฌ idList.rest; ENDLOOP; IO.PutF1[out, " writing to %g\n", [rope[arg]]]; TiogaAccess.WriteFile[writer, arg]; }; symTab ฌ NIL; xrefName ฌ NIL; filesRead ฌ 0; }; indent: INTEGER ฌ 0; symTab: SymTab.Ref ฌ NIL; idList: LIST OF REF ANY ฌ NIL; cToken: REF TEXT ฌ NEW[TEXT[128]]; xrefName: ROPE ฌ NIL; filesRead: INT ฌ 0; tokensRead: INT ฌ 0; uniqueTokensRead: INT ฌ 0; fileListHead: LIST OF ROPE ฌ NIL; fileListTail: LIST OF ROPE ฌ NIL; argv: CommanderOps.ArgumentVector ฌ CommanderOps.Parse[cmd ! CommanderOps.Failed => {msg ฌ errorMsg; GO TO failed}]; FOR i: NAT IN [1..argv.argc) DO arg: ROPE ฌ argv[i]; Process.CheckForAbort[]; SELECT TRUE FROM Rope.Length[arg] = 0 => {}; Rope.Fetch[arg, 0] = '- => ProcessSwitches[arg]; Rope.Equal[arg, "_"] => {}; (i+1) < argv.argc AND Rope.Equal[argv[i+1], "_"] => xrefName ฌ arg; ENDCASE => { { ENABLE { PFS.Error => {msg ฌ error.explanation; GO TO cleanUp}; DFUtilities.SyntaxError => {msg ฌ reason; GO TO cleanUp}; }; EachFile: DFUtilities.ProcessItemProc = { WITH item SELECT FROM fileItem: REF DFUtilities.FileItem => { fName: ROPE = fileItem.name; SELECT TRUE FROM Rope.Match["*.mesa!*", fName, FALSE], Rope.Match["*.mesa", fName, FALSE] => { sName: ROPE = GetShortName[fName]; name: ROPE ฌ sName; date: BasicTime.GMT ฌ BasicTime.nullGMT; st: STREAM ฌ NIL; IF NOT switches['h] THEN { name ฌ Rope.Concat[path, sName]; date ฌ fileItem.date.gmt; }; st ฌ OpenRead[name, date ! PFS.Error => IF error.code = $unknownFile AND switches['h] THEN CONTINUE]; IF st = NIL THEN { name ฌ Rope.Concat[path, sName]; st ฌ OpenRead[name]; }; EachStream[st, TRUE]; }; ENDCASE; }; dirItem: REF DFUtilities.DirectoryItem => path ฌ dirItem.path1; inclItem: REF DFUtilities.IncludeItem => EachDF[inclItem.path1, inclItem.date.gmt]; ENDCASE; }; EachDF: PROC [dfName: ROPE, date: BasicTime.GMT ฌ BasicTime.nullGMT] = { inclStream: STREAM ฌ NIL; sName: ROPE = GetShortName[dfName]; ReportName[sName]; inclStream ฌ OpenRead[dfName, date]; indent ฌ indent + 2; DFUtilities.ParseFromStream[ inclStream, EachFile, [filterA: source, filterC: defining] ! UNWIND => IO.Close[inclStream]]; IO.Close[inclStream]; indent ฌ indent - 2; }; EachName: PFS.NameProc = { fullFName: ROPE ฌ PFS.RopeFromPath[name]; locName: ROPE ฌ NIL; continue ฌ TRUE; IF xrefName = NIL THEN { sName: ROPE ฌ GetShortName[fullFName]; pos: INT ฌ Rope.Length[sName]; xrefName ฌ Rope.Flatten[sName]; WHILE pos > 0 DO SELECT Rope.Fetch[xrefName, pos-1] FROM '! => xrefName ฌ Rope.Flatten[xrefName, 0, pos-1]; '. => {xrefName ฌ Rope.Flatten[xrefName, 0, pos-1]; EXIT}; ENDCASE; pos ฌ pos - 1; ENDLOOP; xrefName ฌ Rope.Concat[xrefName, ".xref"]; }; SELECT TRUE FROM (locName ฌ FileWithSearchRules[fullFName, ".mesa"]) # NIL => EachStream[OpenRead[locName], TRUE]; (locName ฌ FileWithSearchRules[fullFName, ".tioga"]) # NIL => EachStream[OpenRead[locName], FALSE]; (locName ฌ FileWithSearchRules[fullFName, ".df"]) # NIL => IF switches['s] THEN EachStream[OpenRead[locName], FALSE] ELSE EachDF[locName]; switches['t] => EachStream[OpenRead[fullFName], FALSE]; ENDCASE => IO.PutF1[out, "-- Warning: %g was not found.\n", [rope[fullFName]] ]; }; path: ROPE ฌ NIL; IF Rope.SkipTo[arg, 0, "*"] # Rope.Length[arg] THEN { IF Rope.SkipTo[arg, 0, "!"] = Rope.Length[arg] THEN arg ฌ Rope.Concat[arg, "!h"]; PFS.EnumerateForNames[PFS.PathFromRope[arg], EachName]; } ELSE [] ฌ EachName[PFS.PathFromRope[arg]]; EXITS cleanUp => { FOR each: LIST OF REF ANY ฌ idList, each.rest WHILE each # NIL DO WITH each.first SELECT FROM entry: REF IdEntry => { ring: LIST OF IdRef ฌ entry.refs; entry.refs ฌ NIL; IF ring # NIL THEN ring.rest ฌ NIL; }; ENDCASE; ENDLOOP; symTab ฌ NIL; GO TO failed; }; }; }; ENDLOOP; IF filesRead # 0 THEN DumpXref[xrefName]; EXITS failed => {result ฌ $Failure}; }; AddReserved: PROC [symTab: SymTab.Ref, rope: ROPE] = { pos: INT ฌ 0; len: INT ฌ Rope.Length[rope]; DO next: INT ฌ Rope.SkipTo[rope, pos, " "]; flat: ROPE ฌ Rope.Flatten[rope, pos, next-pos]; new: REF IdEntry ฌ NEW[IdEntry ฌ [name: flat, reserved: Atom.MakeAtom[flat]]]; [] ฌ SymTab.Store[symTab, flat, new]; pos ฌ Rope.SkipOver[rope, next, " "]; IF pos = len THEN EXIT; ENDLOOP; }; MySort: List.CompareProc = { name1: ROPE = NARROW[ref1, REF IdEntry].name; name2: ROPE = NARROW[ref2, REF IdEntry].name; IF name1 = name2 THEN RETURN [equal]; SELECT Rope.Compare[name1, name2, FALSE] FROM less => RETURN [less]; greater => RETURN [greater]; ENDCASE => RETURN [Rope.Compare[name1, name2, TRUE]]; }; OpenRead: PROC [name: ROPE, time: BasicTime.GMT ฌ BasicTime.nullGMT] RETURNS [STREAM] = { path: PFS.PATH = PFS.PathFromRope[name]; st: STREAM = PFS.StreamOpen[fileName: path, wantedUniqueID: [[time, 0], [0, 0]]]; RETURN [st]; }; GetShortName: PROC [name: ROPE] RETURNS [ROPE] = { RETURN [PFSNames.ShortNameRope[PFSNames.StripVersionNumber[PFS.PathFromRope[name]]]]; }; FileWithSearchRules: PROC [name: ROPE, ext: ROPE] RETURNS [ROPE] = { ret: ROPE ฌ name; path: PFS.PATH = PFSNames.StripVersionNumber[PFS.PathFromRope[name]]; sn: ROPE = PFSNames.ShortNameRope[path]; posExt: INT = Rope.FindBackward[sn, ext]; posDot: INT = Rope.FindBackward[sn, "."]; IF posExt < 0 THEN ret ฌ NIL; IF posDot < 0 THEN { snPath: PFS.PATH = PFS.PathFromRope[Rope.Concat[sn, ext]]; newPath: PFS.PATH = PFSNames.StripVersionNumber[ PFSNames.ReplaceShortName[path, PFSNames.ShortName[snPath]]]; realPath: PFS.PATH = PFS.FileInfo[newPath ! PFS.Error => GO TO beep].fullFName; ret ฌ PFS.RopeFromPath[realPath]; EXITS beep => ret ฌ NIL; }; RETURN [ret]; }; doc: ROPE = "takes cross-references of Cedar source files listed in the given DF files -d: print warnings on definitions only -f: print full file names -h: use local highest versions of files -s: shallow, don't follow df files -t: text file, not Cedar tokens -v: verbose (print positions, Tioga formatting)"; Commander.Register[ key: "XRef", proc: DoCommandProc, doc: doc, clientData: NIL, interpreted: TRUE ]; END. ย XRef.mesa Copyright ำ 1986, 1987, 1989, 1991, 1992 by Xerox Corporation. All rights reserved. Russ Atkinson (RRA) December 27, 1991 6:31 pm PST [cmd: Handle] RETURNS [result: REF _ NIL, msg: ROPE _ NIL] CommandObject = [in, out, err: STREAM, commandLine, command: ROPE, ...] Takes an open stream and adds the info to the xref. text, not Cedar/Mesa Could be a reference Cedar/Mesa reserved words derived from Pass1T.mesa Cedar/Mesa built-in types derived from Pass1.mesa Now we can put out the cross-reference [c: CHAR] RETURNS [quit: BOOL _ FALSE] When parsing the command line, be prepared for failure. The error is reported to the user Each argument can either be a switch specification or a genuine argument to be processed. The first argument (argv[0]) is not examined, because by convention it is the name of the command as given by the user. It is a good idea to periodically check for a process abort request. [item: REF ANY] RETURNS [stop: BOOL _ FALSE] The local open failed because there was no local version, so try the remote version (with the highest version number). [name: PATH] RETURNS [continue: BOOL] A pattern to enumerate Appears to be a single file The idea is to charge down the list, breaking the circularities as we go. [ref1: REF ANY, ref2: REF ANY] RETURNS [Basics.Comparison] The name does not have the desired extension This name does not have the desired extension, and does not have a dot, so let's try to add the desired extension. สK–(cedarcode) style•NewlineDelimiter ™headšœ ™ Icodešœ ฯeœI™TL™1—˜šฯk ˜ Lšœžœ ˜Lšœžœ˜Lšœ žœžœ˜$Lšœ žœ˜(Lšœ žœ!˜3Lšœžœ ˜Lšœ žœW˜hLšžœžœzžœ ˜•Lšœžœ˜(LšžœžœMžœ*˜„Lšœ žœB˜PLšœžœ˜Lšœžœ%˜2Lšœžœežœ˜‡Lšœžœ!˜-Lšœ žœ-˜>L˜——šฯnœžœž˜LšžœAžœžœ7˜ŒLšœž˜—˜Lšžœžœžœ˜Lšžœžœžœžœ˜L˜šœ žœžœ˜Lšœžœ˜ Lšœžœžœ žœ˜Lšœ žœžœ˜L˜—šœžœžœ˜Lšœ žœฯc#˜3Lšœžœ ˜,Lšœžœ !˜.——L˜šŸ œ˜(š œžœ žœžœžœžœ™:Lšœžœžœ™G—Lšœžœ ˜Lšœ žœžœžœ žœžœžœžœ˜9šŸœžœžœ˜%Lšœžœžœ˜šžœžœžœž˜*Lšœžœ˜$šžœž˜Lšœžœ˜ Lšœžœžœ˜ Lšœ žœžœ˜3Lšžœ$˜&Lšžœ.˜0Lšžœ˜—Lšœžœ˜Lšœžœ˜ Lšžœ˜—L˜—Lšœžœžœ˜šŸ œžœ žœžœ˜1Lšœ3™3Lšœ žœ˜Lšœ žœ˜Lšœžœ žœ˜Lšœ žœ˜Lšœ žœžœ˜Lšœžœžœ˜šŸœžœ žœžœ ˜(Lšœžœžœ˜"šžœž˜ šžœ˜Lšœ žœ˜L˜L˜(L˜—šžœ˜L˜L˜L˜——L˜L˜L˜—Lš œ žœžœžœ žœ(˜\Lšžœžœžœ)˜ALšœ˜L˜šžœž˜Lšžœžœ ˜4Lšžœ%žœ˜<—Lšžœ žœžœ ˜!šžœ ˜šžœ˜L™Lšœžœ˜ šž˜Lš œžœžœžœžœ˜6šžœž˜ Lšžœ žœ˜Lšžœžœ˜—L˜L˜Lšœžœ˜ šž˜Lš œžœžœžœžœ˜6šžœž˜ šžœ žœ žœ˜,L˜-—Lšžœžœ˜—Lšžœ˜—šžœ&žœž˜5Lšœžœ˜šžœ˜ Lšœžœ žœ-˜CL˜)L˜ L˜——Lšœžœžœ˜*Lšžœ˜—L˜—šžœ˜šž˜Lšœ žœ ˜L˜Lšœ(žœ˜Išžœ ž˜šœ˜šžœ ž˜L˜&L˜&Lšœžœžœžœ˜5šœžœžœžœ˜Lšœžœ˜ Lšœžœžœžœ˜5L˜Lšžœžœžœžœ˜'L˜—Lšœžœ˜ Lšœžœžœ ˜Lšžœ˜—šž˜˜ Lšœžœ˜——L˜—šœ ˜ šžœ&žœž˜5šœžœ ˜šžœ ž˜šžœ˜L˜ Lšžœžœ˜L˜—L˜&šœ ˜ Lšœžœ˜ Lšœžœžœžœ˜5L˜Lšžœžœžœžœ˜'L˜—Lšœžœžœžœ˜>Lšœ žœžœ˜$Lšœžœžœžœ˜4Lšžœ˜—Lšœžœ˜Lšžœ˜ L˜—šžœ˜ Lšœžœ žœ-˜CL˜)L˜ Lšžœžœ˜L˜——šžœ˜Lšžœžœžœ˜Lšœžœžœ ˜/Lšœžœžœ˜Lšœžœ˜ Lšœžœžœžœ˜ -- [ref1: REF ANY, ref2: REF ANY] RETURNS [Basics.Comparison]šŸœ˜Lšก:™:Lšœžœžœžœ˜-Lšœžœžœžœ˜-Lšžœžœžœ ˜%šžœžœž˜-Lšœžœ˜Lšœ žœ ˜Lšžœžœžœ˜5—L˜L˜—š Ÿœžœžœžœžœžœ˜YLšœžœžœžœ˜(LšœžœžœA˜QLšžœ˜ L˜L˜—š Ÿ œžœžœžœžœ˜2Lšžœ5žœ˜UL˜L˜—š Ÿœžœžœžœžœžœ˜DLšœžœ˜Lšœžœžœžœ˜ELšœžœ ˜(Lšœžœ˜)Lšœžœ˜)šžœ žœžœ˜L™,—šžœ žœ˜L™rLšœžœžœžœ$˜:Lšœ žœžœ]˜nLš œ žœžœžœžœ žœžœ˜OLšœžœ˜!Lšžœžœ˜L˜—Lšžœ˜ L˜L˜—Lšœžœร˜ฬL˜–x[key: ROPE, proc: Commander.CommandProc, doc: ROPE _ NIL, clientData: REF ANY _ NIL, interpreted: BOOL _ TRUE]šœ˜Lšœ ˜ Lšœ˜Lšœ ˜ Lšœ žœ˜Lšœ ž˜Lšœ˜—L˜Lšžœ˜L˜šœ˜L™——…—A>bK