DIRECTORY Commander USING [Handle], CommanderOps USING [ArgumentVector, ArgHandleObject], IO USING [EndOfStream, Error, GetIndex, GetRopeLiteral, PutChar, RopeFromROS, RIS, ROS, SetIndex, STREAM], PositionedList USING [ PositionedArgumentList, PositionedArgumentVector, PositionedArgumentVectorPrivate, PositionedArgument ], Rope USING [Fetch, Length, ROPE, Size]; PositionedListImpl: CEDAR PROGRAM IMPORTS IO, Rope EXPORTS PositionedList ~ { OPEN PositionedList; Failed: ERROR [errorMsg: ROPE] = CODE; QuoteSyntaxError: ERROR = CODE; CPData: TYPE = RECORD [ ch: CHAR _ ' , -- first char of next token; initially blank swChar: CHAR, -- switch character ropeIndex: LONG INTEGER _ 0, -- index into Rope command line rope: ROPE _ NIL, -- command line passed from client done: BOOL _ FALSE -- used up all of command line ]; Handle: TYPE = Commander.Handle; ROPE: TYPE = Rope.ROPE; STREAM: TYPE = IO.STREAM; ParseToPositionedList: PUBLIC PROC [cmd: Handle, switchChar: CHAR ¬ '-] RETURNS [list: PositionedArgumentList, length: NAT ¬ 1] = { cpd: REF CPData ¬ NEW[CPData]; tail: PositionedArgumentList ¬ list ¬ LIST[[-cmd.command.Length, -1, cmd.command]]; cpd.swChar ¬ switchChar; cpd.rope ¬ cmd.commandLine; DO r: PositionedArgument ¬ IGet[cpd ! QuoteSyntaxError => GOTO Lose]; IF r.rope = NIL THEN EXIT; length ¬ length + 1; tail ¬ tail.rest ¬ LIST[r]; ENDLOOP; EXITS Lose => Failed["Syntax error in quoted string"]; }; IGet: PROC [cpd: REF CPData] RETURNS [result: PositionedArgument] = { workstr: STREAM ¬ NIL; chlook: CHAR; WHILE (cpd.ch = ' OR cpd.ch = ' ) AND GetCh[cpd] DO ENDLOOP; IF cpd.done OR cpd.ch = '\n OR cpd.ch = '\l THEN RETURN [[0, -1, NIL]]; result.start ¬ cpd.ropeIndex-1; chlook ¬ ' ; IF cpd.ch = '" THEN --this makes the later code that considers that chlook might be '" obsolete (as of July 16th 1987), but we're chicken and so haven't deleted it yet--{ workstr ¬ IO.RIS[cpd.rope]; workstr.SetIndex[result.start]; result.rope ¬ IO.GetRopeLiteral[workstr !IO.Error, IO.EndOfStream => ERROR QuoteSyntaxError]; cpd.ropeIndex ¬ IO.GetIndex[workstr]; result.length ¬ cpd.ropeIndex - result.start; [] ¬ GetCh[cpd]; RETURN}; DO IF cpd.done OR (chlook # '" AND (cpd.ch = '\n OR cpd.ch = '\l) ) THEN GOTO EOL; SELECT chlook FROM ' , '\t => SELECT cpd.ch FROM ' , '", '\t => IF workstr # NIL THEN EXIT; cpd.swChar => IF cpd.ch#'- AND workstr#NIL THEN EXIT; ENDCASE; '" => SELECT cpd.ch FROM '" => IF (NOT GetCh[cpd]) OR (cpd.ch # '") THEN EXIT; ENDCASE; ENDCASE => ERROR; IF workstr = NIL THEN workstr ¬ IO.ROS[]; IO.PutChar[workstr, cpd.ch]; IF NOT GetCh[cpd] THEN GOTO EOL; REPEAT EOL => IF chlook = '" THEN ERROR QuoteSyntaxError; ENDLOOP; IF workstr = NIL THEN RETURN [[0, -1, NIL]]; result.length ¬ cpd.ropeIndex - (IF cpd.done THEN 0 ELSE 1) - result.start; result.rope ¬ IO.RopeFromROS[workstr]; RETURN}; GetCh: PROC [cpd: REF CPData] RETURNS [BOOL] = { IF cpd.ropeIndex >= Rope.Size[cpd.rope] THEN GOTO EOS; cpd.ch ¬ Rope.Fetch[cpd.rope, cpd.ropeIndex]; cpd.ropeIndex ¬ SUCC[cpd.ropeIndex]; RETURN [TRUE]; EXITS EOS => { cpd.done ¬ TRUE; cpd.ch ¬ ' ; RETURN [FALSE]; }; }; ParsePositioned: PUBLIC PROC [cmd: Handle, switchChar: CHAR ¬ '-] RETURNS [argv: PositionedArgumentVector] = { list: PositionedArgumentList ¬ NIL; nArgs: NAT ¬ 0; [list, nArgs] ¬ ParseToPositionedList[cmd: cmd, switchChar: switchChar]; argv ¬ NEW[PositionedArgumentVectorPrivate[nArgs]]; FOR i: NAT IN [0..nArgs) DO argv[i] ¬ list.first; list ¬ list.rest; ENDLOOP; RETURN}; StripVectorPositions: PUBLIC PROC [pargv: PositionedArgumentVector] RETURNS [argv: CommanderOps.ArgumentVector] ~ { argv ¬ NEW [CommanderOps.ArgHandleObject[pargv.argc]]; FOR i: NAT IN [0 .. argv.argc) DO argv[i] ¬ pargv[i].rope ENDLOOP; RETURN}; StripListPositions: PUBLIC PROC [plist: PositionedArgumentList] RETURNS [list: LIST OF ROPE] = { tail: LIST OF ROPE ¬ NIL; FOR plist ¬ plist, plist.rest WHILE plist#NIL DO this: LIST OF ROPE ~ LIST[plist.first.rope]; IF tail=NIL THEN list ¬ this ELSE tail.rest ¬ this; tail ¬ this; ENDLOOP; RETURN}; }. z PositionedListImpl.mesa Copyright Σ 1984, 1985, 1986, 1987, 1989, 1993 by Xerox Corporation. All rights reserved. Swinehart, September 17, 1993 2:03 pm PDT Russ Atkinson (RRA) March 2, 1987 7:36:27 pm PST Last tweaked by Mike Spreitzer on February 22, 1988 6:04:50 pm PST Willie-Sue, April 17, 1989 3:57:09 pm PDT Returns next token. This scanner (1) ignores leading blanks, (2) returns a quoted token intact (excluding the quotes), (3) returns an unquoted token delimited by a blank (not included) or switchchar (included in next token), the default switchchar is '- (4) returns NIL at CR or end of file. (5) if the switchchar is '- then it must be preceded by a blank delimiter for token: either blank, meaning blank or switchchar (usually '-), or '", or '", meaning '" not followed by another '". '/l also delimits a line ch now contains a character to be included in the token Κ{•NewlineDelimiter ™code™Kšœ ΟeœO™ZK™)K™0K™BK™)K˜—šΟk ˜ Kšœ žœ ˜Kšœ žœ#˜5Kš žœžœFžœžœ žœ˜jKšœžœk˜Kšœžœžœ˜'—headšœœžœž˜!Kšžœžœ˜šžœ˜Kšžœ˜K˜—KšΟnœžœ žœžœ˜&KšŸœžœžœ˜K˜šœžœžœ˜KšœžœΟc,˜;Kšœžœ ˜!Kšœ žœžœ ˜=Kšœžœžœ "˜4Kšœžœžœ ˜1K˜K˜—Kšœžœ˜ Kšžœžœžœ˜Kšžœžœžœžœ˜˜K˜——š Ÿœžœžœžœžœ(žœ ˜ƒKšœžœ žœ ˜Kšœ&žœ)˜SK˜K˜šž˜Kšœ7žœ˜BKšžœ žœžœžœ˜K˜Kšœžœ˜Kšžœ˜—Kšžœ1˜6K˜K˜—šŸœžœžœ žœ!˜Ešœ ™ Kšœ™Kšœ9™9Kšœ†™†Kšœ žœžœ™%Kšœ?™?—Kšœ žœžœ˜šœžœ˜ Kšœ0™0Kšœ™Kšœ4™4K˜—Kš žœžœžœ žœžœ˜=K™Kš žœ žœžœžœžœ žœ˜GK˜K˜ šžœ žœ ZΠcu 9œ˜ͺKšœ žœžœ ˜Kšœ˜Kš œžœžœžœžœ˜]Kšœžœ˜%K˜-K˜Kšžœ˜—šž˜Kšžœ žœžœžœžœžœžœ˜Ošžœž˜šœ žœž˜Kš œžœ žœžœžœ˜+Kš œžœ žœ žœžœžœ˜5Kšžœ˜—šœžœž˜Kš œžœžœ žœžœžœ˜5Kšžœ˜—Kšžœžœ˜—Kšœ7™7Kš žœ žœžœ žœžœ˜)Kšžœ˜Kš žœžœ žœžœžœ˜ šž˜Kšžœžœ žœžœ˜2—Kšžœ˜—Kš žœ žœžœžœ žœ˜,Kšœ!žœ žœžœ˜KKšœžœ˜&Kšžœ˜K˜—š Ÿœžœžœ žœžœ˜0Kšžœ&žœžœžœ˜6K˜-Kšœžœ˜$Kšžœžœ˜šž˜šžœ˜Kšœ žœ˜K˜ Kšžœžœ˜K˜——Kšœ˜K˜—š Ÿœžœžœžœžœ%˜nKšœžœ˜#Kšœžœ˜K˜HKšœžœ)˜3šžœžœžœ ž˜K˜K˜Kšžœ˜—Kšžœ˜K˜—šŸœžœžœ#žœ(˜sKšœžœ,˜6Kš žœžœžœžœžœ˜BKšžœ˜K˜—šŸœžœžœ!žœžœžœžœ˜`Kš œžœžœžœžœ˜šžœžœžœž˜0Kš œžœžœžœžœ˜,Kšžœžœžœ žœ˜3K˜ Kšžœ˜—Kšžœ˜—J˜—…—Ύ³