[m-rev.] diff: .NET: fix io__putback_char

Fergus Henderson fjh at cs.mu.OZ.AU
Fri Oct 25 01:12:59 AEST 2002


Estimated hours taken: 3
Branches: main

Fix a bug that broke tests/hard_coded/term_io_test in grade il.

library/io.m:
	Implement io__putback_char and io__putback_byte properly for
	the .NET back-end.  The previous implementations were buggy:
	among other things, they did not handle non-seekable streams,
	such as stdin.

Workspace: /c/fjh/ws/2/mercury
Index: library/io.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/io.m,v
retrieving revision 1.269
diff -u -d -r1.269 io.m
--- library/io.m	19 Oct 2002 14:10:51 -0000	1.269
+++ library/io.m	24 Oct 2002 15:14:13 -0000
@@ -3440,6 +3440,9 @@
 
 	System::IO::Stream 	*stream; // The stream itself
 	System::IO::TextReader 	*reader; // A stream reader for reading it
+	int			putback;
+			// the next character or byte to read,
+			// or -1 if no putback char/byte is stored
 	System::IO::TextWriter 	*writer; // A stream writer for writing it
 	ML_file_encoding_kind	file_encoding; // DOS, Unix, or raw binary
 	int			line_number;
@@ -3522,6 +3525,7 @@
 	MR_MercuryFile mf = new MR_MercuryFileStruct();
 	mf->stream = stream;
 	mf->reader = reader;
+	mf->putback = -1;
 	mf->writer = writer;
 	mf->file_encoding = file_encoding;
 	mf->line_number = 1;
@@ -3545,6 +3549,7 @@
 	mercury_file_init(System::Console::OpenStandardError(),
 	    NULL, System::Console::Error, ML_default_text_encoding);
 
+	// XXX should we use BufferedStreams here?
 static MR_MercuryFile mercury_stdin_binary =
 	mercury_file_init(System::Console::OpenStandardInput(),
 	    System::Console::In, NULL, ML_raw_binary);
@@ -3557,6 +3562,7 @@
 static MR_MercuryFile mercury_current_binary_input = mercury_stdin_binary;
 static MR_MercuryFile mercury_current_binary_output = mercury_stdout_binary;
 
+// XXX not thread-safe! */
 static System::IO::IOException *MR_io_exception;
 
 ").
@@ -3621,6 +3627,8 @@
         if (!stream) {
                 return 0;
         } else {
+		stream = new System::IO::BufferedStream(stream);
+		
 		// we initialize the `reader' and `writer' fields to null;
 		// they will be filled in later if they are needed.
                 mf = mercury_file_init(stream, NULL, NULL, file_encoding);
@@ -3855,6 +3863,12 @@
 {
 	int c;
 
+	if (mf->putback != -1) {
+		c = mf->putback;
+		mf->putback = -1;
+		return c;
+	}
+
 	if (mf->reader == NULL) {
 		mf->reader = new System::IO::StreamReader(mf->stream,
 				System::Text::Encoding::Default);
@@ -3899,6 +3913,18 @@
         return c;
 }
 
+static void
+mercury_ungetc(MR_MercuryFile mf, int code)
+{
+	if (mf->putback != -1) {
+		mercury::runtime::Errors::SORRY(
+			""mercury_ungetc: max one character of putback"");
+	}
+	mf->putback = code;
+	if (code == '\\n') {
+		mf->line_number--;
+	}
+}
 ").
 
 
@@ -4169,30 +4195,34 @@
 		[will_not_call_mercury, promise_pure], "
 	MR_MercuryFile mf = ML_DownCast(MR_MercuryFile, 
 		MR_word_to_c_pointer(File));
-	ByteVal = mf->stream->ReadByte();
+	if (mf->putback != -1) {
+		ByteVal = mf->putback;
+		mf->putback = -1;
+	} else {
+		ByteVal = mf->stream->ReadByte();
+	}
 	MR_update_io(IO0, IO);
 ").
 
 :- pragma foreign_proc("MC++", 
 	io__putback_char(File::in, Character::in, IO0::di, IO::uo),
 		[may_call_mercury, promise_pure], "{
-	// XXX This is wrong; it doesn't handle CR-LF properly.
-
 	MR_MercuryFile mf = ML_DownCast(MR_MercuryFile,
 		MR_word_to_c_pointer(File));
-	if (Character == '\\n') {
-		mf->line_number--;
-	}
-	mf->stream->Seek(-1, System::IO::SeekOrigin::Current);
+	mercury_ungetc(mf, Character);
 	MR_update_io(IO0, IO);
 }").
 
 :- pragma foreign_proc("MC++",
-	io__putback_byte(File::in, _Character::in, IO0::di, IO::uo),
+	io__putback_byte(File::in, Byte::in, IO0::di, IO::uo),
 		[may_call_mercury, promise_pure], "{
 	MR_MercuryFile mf = ML_DownCast(MR_MercuryFile, 
 		MR_word_to_c_pointer(File));
-	mf->stream->Seek(-1, System::IO::SeekOrigin::Current);
+	if (mf->putback != -1) {
+		mercury::runtime::Errors::SORRY(
+			""io__putback_byte: max one character of putback"");
+	}
+	mf->putback = Byte;
 	MR_update_io(IO0, IO);
 }").
 
--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list