Selaa lähdekoodia

improved compatibility of shell between native A2 / WinA2 / LinuxA2

git-svn-id: https://svn.inf.ethz.ch/svn/lecturers/a2/trunk@7398 8c9fc860-2736-0410-a75d-ab315db34111
felixf 7 vuotta sitten
vanhempi
commit
7e1cf9c917
2 muutettua tiedostoa jossa 20 lisäystä ja 15 poistoa
  1. 8 3
      source/InterpreterShell.Mod
  2. 12 12
      source/Shell.Mod

+ 8 - 3
source/InterpreterShell.Mod

@@ -181,6 +181,7 @@ TYPE
 		nestingLevel : LONGINT; (* how many shells run in this shell? *)
 		aliases: Alias;
 		prompt: ARRAY 32 OF CHAR;
+		seenCR: CHAR;
 
 		(* Connection to the entiry hosting this shell instance *)
 		upcall : NotifyProcedure;
@@ -257,9 +258,13 @@ TYPE
 
 					IF IsControlCharacter(ch) OR (ch = Delete) THEN
 
-						IF (*(ch = CR) OR*) (ch = LF) OR (ch = Streams.EOT) OR (context.in.res # Streams.Ok) THEN
-							EXIT
 
+						IF ((ch = CR) OR (ch = LF)) OR (ch = Streams.EOT) OR (context.in.res # Streams.Ok) THEN
+							IF seenCR = 0X THEN seenCR := ch 
+							ELSIF seenCR = ch THEN 
+								EXIT
+							ELSE (* ignore *)
+							END;
 						ELSIF (ch = Backspace) OR (ch = Delete)THEN
 							IF currentIndex >= 0 THEN (* There is a character at the left of the cursor *)
 								command[currentIndex] := 0X;
@@ -296,7 +301,7 @@ TYPE
 
 			command[currentIndex+1] := 0X;
 
-			IF (* (ch = CR) OR*)  (ch = LF) THEN
+			IF (ch = CR) OR  (ch = LF) THEN
 				commandHistory.AddCommand(command);
 				(*IF (*(ch = CR) & *)(context.in.Available() > 0) & (context.in.Peek() = LF) THEN ch := context.in.Get() END;*)
 				IF echo THEN context.out.Ln; context.out.Update END

+ 12 - 12
source/Shell.Mod

@@ -148,13 +148,14 @@ TYPE
 		upcall : NotifyProcedure;
 
 		commandHistory : CommandHistory;
+		firstCR : CHAR;
 
 		PROCEDURE &Init*(in: Streams.Reader; out, err: Streams.Writer; echo: BOOLEAN; CONST prompt: ARRAY OF CHAR);
 		BEGIN
 			ASSERT((in # NIL) & (out # NIL) & (err # NIL));
 			NEW(context, in, NIL, out, err, SELF);
 			close := FALSE; dead := FALSE; command[0] := 0X; res := 0; SELF.echo := echo; COPY(prompt, SELF.prompt);
-			NEW(commandHistory);
+			NEW(commandHistory); firstCR := 0X;
 		END Init;
 
 		PROCEDURE Exit*;
@@ -218,13 +219,17 @@ TYPE
 
 					IF IsControlCharacter(ch) OR (ch = Delete) THEN
 
-						IF (ch = CR) OR (ch = LF) OR (ch = Streams.EOT) OR (context.in.res # Streams.Ok) THEN
+						IF (ch = CR) OR (ch = LF) THEN
 							(* skip redundant CR and LF to avoid generation of empty commands. This requires peek functionality which doesn't work on the Input stream from an underlying OS, so a decoupler is needed that transforms that into an oberon stream*)
-							WHILE (context.in.res = Streams.Ok) & (context.in.Available() # 0) & ((context.in.Peek() = CR) OR (context.in.Peek() = LF)) DO
-								context.in.SkipBytes(1);
+							(* actually: it is much simpler: just memorize the first seen CR or LF and start executing from there *)
+							IF firstCR = 0X THEN
+								firstCR := ch;
+								EXIT;
+							ELSIF ch = firstCR THEN
+								EXIT
 							END;
-							ch := LF;
-							EXIT
+						ELSIF (ch = Streams.EOT) OR (context.in.res # Streams.Ok) THEN
+							EXIT;
 						ELSIF (ch = Backspace) OR (ch = Delete)THEN
 							IF currentIndex >= 0 THEN (* There is a character at the left of the cursor *)
 								command[currentIndex] := 0X;
@@ -260,7 +265,7 @@ TYPE
 			END;
 			command[currentIndex+1] := 0X;
 
-			IF (ch = LF) (*OR (ch =CR)*)  THEN
+			IF (ch = LF) OR (ch =CR)  THEN
 				commandHistory.AddCommand(command);
 				
 				IF echo THEN context.out.Ln; context.out.Update END
@@ -591,11 +596,6 @@ TYPE
 						Execute(cmdList, wait, exit)
 					END
 				END;
-				(* do this here because Available can block for in-streams in WIndows/Linux *)
-				(*
-				IF (context.in.Available() > 0) & ((ch = CR) & (context.in.Peek() = LF) OR (ch = LF) & (context.in.Peek() = CR)) THEN ch := context.in.Get() END;
-				*)
-
 			END;
 			context.out.Update; context.error.Update
 		END Run;