2
0
Эх сурвалжийг харах

Add StdIo also for windows.
Enabled shell in Windows and Linux.



git-svn-id: https://svn.inf.ethz.ch/svn/lecturers/a2/trunk@6936 8c9fc860-2736-0410-a75d-ab315db34111

felixf 8 жил өмнө
parent
commit
4331b1edc7

+ 4 - 1
source/Generic.Linux.I386.Glue.Mod

@@ -225,13 +225,16 @@ SystemTools.DoCommands
 		UTF8Strings.Mod FileTrapWriter.Mod Caches.Mod DiskVolumes.Mod OldDiskVolumes.Mod RAMVolumes.Mod 
 		UTF8Strings.Mod FileTrapWriter.Mod Caches.Mod DiskVolumes.Mod OldDiskVolumes.Mod RAMVolumes.Mod 
 		DiskFS.Mod OldDiskFS.Mod OberonFS.Mod FATVolumes.Mod FATFiles.Mod ISO9660Volumes.Mod 
 		DiskFS.Mod OldDiskFS.Mod OberonFS.Mod FATVolumes.Mod FATFiles.Mod ISO9660Volumes.Mod 
 		ISO9660Files.Mod Unix.UnixFiles.Mod RelativeFileSystem.Mod BitSets.Mod StringPool.Mod DIagnostics.Mod ObjectFile.Mod GenericLinker.Mod GenericLoader.Mod Unix.BootConsole.Mod 
 		ISO9660Files.Mod Unix.UnixFiles.Mod RelativeFileSystem.Mod BitSets.Mod StringPool.Mod DIagnostics.Mod ObjectFile.Mod GenericLinker.Mod GenericLoader.Mod Unix.BootConsole.Mod 
+		Pipes.Mod Shell.Mod TestStdIO.Mod
 		TestLinux.Mod  ~
 		TestLinux.Mod  ~
 
 
 	StaticLinker.Link --fileFormat=Raw --fileName=simple_elf --extension=.GofU --displacement=08048000H
 	StaticLinker.Link --fileFormat=Raw --fileName=simple_elf --extension=.GofU --displacement=08048000H
 		Runtime Trace Glue Unix Machine Heaps Modules Objects Kernel KernelLog 
 		Runtime Trace Glue Unix Machine Heaps Modules Objects Kernel KernelLog 
 Streams Commands StdIO TrapWriters Traps 
 Streams Commands StdIO TrapWriters Traps 
 Files UnixFiles Clock Dates Reals Strings Diagnostics 
 Files UnixFiles Clock Dates Reals Strings Diagnostics 
-BitSets StringPool ObjectFile GenericLinker Reflection  GenericLoader  BootConsole  
+BitSets StringPool ObjectFile GenericLinker Reflection  GenericLoader  
+Pipes Shell TestStdIo
+(*BootConsole  *)
  ~
  ~
 
 
 	FSTools.CloseFiles simple_elf ~
 	FSTools.CloseFiles simple_elf ~

+ 4 - 2
source/Generic.Unix.Objects.Mod

@@ -911,12 +911,14 @@ TYPE
 		*)
 		*)
 	END Init;
 	END Init;
 	
 	
+	
 	PROCEDURE {FINAL} Final;
 	PROCEDURE {FINAL} Final;
 	BEGIN
 	BEGIN
 		TRACE("FINAL END ");
 		TRACE("FINAL END ");
-		LOOP Unix.ThrSleep( 10 ) END;
-
+		(* LOOP Unix.ThrSleep( 10 ) END; *)
+		(*
 		Machine.Shutdown(FALSE);
 		Machine.Shutdown(FALSE);
+		*)
 	END Final;
 	END Final;
 
 
 
 

+ 12 - 6
source/Shell.Mod

@@ -171,7 +171,7 @@ TYPE
 			FOR i :=	 0 TO len-1 DO context.out.Char(Backspace); END;
 			FOR i :=	 0 TO len-1 DO context.out.Char(Backspace); END;
 		END DeleteStringFromDisplay;
 		END DeleteStringFromDisplay;
 
 
-		PROCEDURE ReadCommand(VAR command : ARRAY OF CHAR);
+		PROCEDURE ReadCommand(VAR command : ARRAY OF CHAR): CHAR;
 		VAR
 		VAR
 			ch: CHAR;
 			ch: CHAR;
 			currentIndex : LONGINT;
 			currentIndex : LONGINT;
@@ -257,11 +257,12 @@ TYPE
 
 
 			command[currentIndex+1] := 0X;
 			command[currentIndex+1] := 0X;
 
 
-			IF ch = CR THEN
+			IF (ch = LF) (*OR (ch =CR)*)  THEN
 				commandHistory.AddCommand(command);
 				commandHistory.AddCommand(command);
-				IF (context.in.Available() > 0) & (context.in.Peek() = LF) THEN ch := context.in.Get() END;
+				
 				IF echo THEN context.out.Ln; context.out.Update END
 				IF echo THEN context.out.Ln; context.out.Update END
 			END;
 			END;
+			RETURN ch;
 		END ReadCommand;
 		END ReadCommand;
 
 
 		PROCEDURE Parse(VAR cmd: Command; VAR wait: BOOLEAN): LONGINT;
 		PROCEDURE Parse(VAR cmd: Command; VAR wait: BOOLEAN): LONGINT;
@@ -570,7 +571,7 @@ TYPE
 		END Execute;
 		END Execute;
 
 
 		PROCEDURE Run;
 		PROCEDURE Run;
-		VAR cmdList: Command; wait, exit: BOOLEAN; i : LONGINT;
+		VAR cmdList: Command; wait, exit: BOOLEAN; i : LONGINT; ch: CHAR; 
 		BEGIN
 		BEGIN
 			exit := FALSE;
 			exit := FALSE;
 			WHILE ~close & ~exit & (context.in.res = Streams.Ok) DO
 			WHILE ~close & ~exit & (context.in.res = Streams.Ok) DO
@@ -581,12 +582,17 @@ TYPE
 					END;
 					END;
 					context.out.Update
 					context.out.Update
 				END;
 				END;
-				ReadCommand(command);
+				ch := ReadCommand(command);
 				IF (context.in.res = Streams.Ok) & (command # "") THEN
 				IF (context.in.res = Streams.Ok) & (command # "") THEN
 					IF (Parse(cmdList, wait) = 0) THEN
 					IF (Parse(cmdList, wait) = 0) THEN
 						Execute(cmdList, wait, exit)
 						Execute(cmdList, wait, exit)
 					END
 					END
-				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;
 			END;
 			context.out.Update; context.error.Update
 			context.out.Update; context.error.Update
 		END Run;
 		END Run;

+ 92 - 0
source/Win32.StdIo.Mod

@@ -0,0 +1,92 @@
+MODULE StdIO;	(** AUTHOR gf;  PURPOSE "Unix standard IO and argument channels *)
+
+(* Commands.Context for programs running outside Aos *)
+
+IMPORT S := SYSTEM, Modules, Commands, Streams, WinTrace, Kernel32;
+
+CONST 
+	AddrSize = SIZEOF( ADDRESS );
+TYPE
+	String=POINTER TO ARRAY OF CHAR;
+VAR 
+	env-: Commands.Context;
+
+	hin-, hout-, herr-: Kernel32.HANDLE;
+
+PROCEDURE Args(): String;
+VAR size, pos: SIZE; i,j: LONGINT; str: String;
+	cmdLine {UNTRACED}: POINTER {UNSAFE} TO ARRAY OF CHAR;
+BEGIN
+	cmdLine := Kernel32.GetCommandLine();
+	pos := 0;
+	WHILE cmdLine[pos] # 0X DO
+		INC(pos);
+	END;
+	size := pos + 1;
+	NEW(str, size);
+	pos := 0;
+	WHILE cmdLine[pos] # 0X DO
+		str[pos] := cmdLine[pos];
+		INC(pos);
+	END;
+	str[pos] := 0X;
+	RETURN str;
+END Args;
+
+PROCEDURE Cleanup;
+BEGIN
+	env.error.Update;
+	env.out.Update
+END Cleanup;
+
+PROCEDURE Setup;
+VAR
+	arg: Streams.StringReader;
+	stdin: Streams.Reader;
+	stdout: Streams.Writer;
+	errout: Streams.Writer;
+	str: String;
+BEGIN
+	WinTrace.OpenConsole;
+	str := Args();
+	TRACE(str^); 
+	NEW( arg, LEN(str) ); arg.Set(str^);
+	NEW( stdin, WinTrace.Receive, 1024 );
+	NEW( stdout, WinTrace.Send, 1024 );
+	NEW( errout, WinTrace.SendError, 512 );
+	NEW( env, stdin, arg, stdout, errout, NIL );
+	Modules.InstallTermHandler( Cleanup )
+END Setup
+
+BEGIN
+	Setup
+END  StdIO.
+
+SystemTools.DoCommands 
+
+	Compiler.Compile  -b=AMD --objectFile=Generic --symbolFile=Textual --newObjectFile  --objectFileExtension=.Gox --symbolFileExtension=.Syx --mergeSections
+		Runtime.Mod Trace.Mod Generic.Win32.Kernel32.Mod Win32.Machine.Mod Heaps.Mod 
+		Generic.Modules.Mod Win32.Objects.Mod Win32.Kernel.Mod KernelLog.Mod Streams.Mod Commands.Mod 
+		I386.Reals.Mod Reflection.Mod Locks.Mod Win32.Clock.Mod Files.Mod Dates.Mod Strings.Mod 
+
+		Win32.WinTrace.Mod Win32.WinFS.Mod 
+
+		Diagnostics.Mod StringPool.Mod BitSets.Mod ObjectFile.Mod 
+		GenericLinker.Mod GenericLoader.Mod Options.Mod Debugging.Mod
+		
+		Win32.StdIO.Mod 		Pipes.Mod Shell.Mod TestStdIO.Mod
+		
+		
+		
+		~ 
+		
+		
+	StaticLinker.Link --fileFormat=PE32CUI --fileName=fox.exe --extension=Gox --displacement=401000H
+		Runtime Trace Kernel32 Machine Heaps Modules Objects Kernel KernelLog Streams Commands Files 
+		WinFS Clock Dates Reals Strings Diagnostics BitSets StringPool ObjectFile GenericLinker Reflection GenericLoader
+		WinTrace StdIO Pipes Shell TestStdIO ~
+		
+		FSTools.CloseFiles fox.exe ~ 
+		
+	~
+

+ 26 - 3
source/Win32.WinTrace.Mod

@@ -5,7 +5,7 @@ IMPORT Kernel32, Modules,Trace,Commands;
 CONST
 CONST
 	none = 0; console = 1; file = 2;
 	none = 0; console = 1; file = 2;
 VAR
 VAR
-	hin-, hout-: Kernel32.HANDLE;
+	hin-, hout-, herr-: Kernel32.HANDLE;
 	mode: LONGINT; (* none, console or file *)
 	mode: LONGINT; (* none, console or file *)
 
 
 (* Sender to be used with Stream.Writer *)
 (* Sender to be used with Stream.Writer *)
@@ -18,11 +18,30 @@ BEGIN
 	END;
 	END;
 END Send;
 END Send;
 
 
+(* Sender to be used with Stream.Writer *)
+PROCEDURE SendError* (CONST buf: ARRAY OF CHAR; ofs, len: LONGINT; propagate: BOOLEAN; VAR res: LONGINT);
+VAR b: Kernel32.BOOL;
+BEGIN
+	IF mode # none THEN
+		b := Kernel32.WriteFile (herr, buf[ofs], len, len, NIL);
+		Kernel32.FlushFileBuffers(herr);
+	END;
+END SendError;
+
+
 (* Receiver to be used with Stream.Reader *)
 (* Receiver to be used with Stream.Reader *)
 PROCEDURE Receive* (VAR buf: ARRAY OF CHAR; ofs, size, min: LONGINT; VAR len, res: LONGINT);
 PROCEDURE Receive* (VAR buf: ARRAY OF CHAR; ofs, size, min: LONGINT; VAR len, res: LONGINT);
-VAR b: Kernel32.BOOL;
+VAR b: Kernel32.BOOL; tlen: LONGINT;
 BEGIN
 BEGIN
-	b := Kernel32.ReadFile (hin, buf[ofs], min, len, NIL);
+	len := 0;
+	b := Kernel32.ReadFile (hin, buf[ofs], size, len, NIL);
+	DEC(size, len);
+	WHILE (len < min) DO
+		b := Kernel32.ReadFile (hin, buf[ofs], size, tlen, NIL);
+		INC(len, tlen);
+		DEC(size, tlen);
+	END;
+	res := 0;
 END Receive;
 END Receive;
 
 
 PROCEDURE Init;
 PROCEDURE Init;
@@ -59,6 +78,9 @@ BEGIN
 	hout := Kernel32.GetStdHandle (Kernel32.STDOutput);
 	hout := Kernel32.GetStdHandle (Kernel32.STDOutput);
 	ASSERT ((hout) # (Kernel32.InvalidHandleValue));
 	ASSERT ((hout) # (Kernel32.InvalidHandleValue));
 
 
+	herr := Kernel32.GetStdHandle (Kernel32.STDError);
+	ASSERT ((herr) # (Kernel32.InvalidHandleValue));
+
 	Trace.Char := Char;
 	Trace.Char := Char;
 	mode := console;
 	mode := console;
 END OpenConsole;
 END OpenConsole;
@@ -70,6 +92,7 @@ BEGIN
 	IF ~context.arg.GetString(filename) THEN filename := "WinTrace.Text" END;
 	IF ~context.arg.GetString(filename) THEN filename := "WinTrace.Text" END;
 	hout := Kernel32.CreateFile(filename, {Kernel32.GenericWrite}, {Kernel32.FileShareRead}, NIL, Kernel32.CreateAlways, {Kernel32.FileAttributeNormal}, Kernel32.NULL);
 	hout := Kernel32.CreateFile(filename, {Kernel32.GenericWrite}, {Kernel32.FileShareRead}, NIL, Kernel32.CreateAlways, {Kernel32.FileAttributeNormal}, Kernel32.NULL);
 	ASSERT ((hout) # (Kernel32.InvalidHandleValue));
 	ASSERT ((hout) # (Kernel32.InvalidHandleValue));
+	herr := hout;
 	Trace.Char := Char;
 	Trace.Char := Char;
 	mode := file;
 	mode := file;
 END OpenFile;
 END OpenFile;