Carve io.stream_ops.m out of io.m.

Also, move foreign code pieces still in io.m that belong in
previously-carved-out modules to those modules.

library/io.m:
library/io.stream_ops.m:
    As above. The new private submodule contains the implementations
    (helper predicates) of the operations that

    - open and close streams,
    - get and set offsets in those streams,
    - get and set line numbers on streams,
    - return the standard streams, and
    - set streams as the current streams.

library/io.m:
    Make some previously private includes public, to allow modules outside
    of io.m to refer to the C# and Java symbols they define. These includes
    are in the second, undocumented interface section of io.m.

    Delete the foreign code moved to io.primitives_{read,write}.m,
    as well as the foreign code moved to io.stream_ops.m.

    Change {get,set}_{line_number,output_line_number}/3, which used
    to be implemented directly using foreign_procs, to implement them
    in terms of their arity-4 counterparts which take an explicit stream
    argument, which now are in io.stream_ops.m. This can yield a slowdown,
    but it should be so small as to be unmeasurable on all non-microbenchmark
    workloads.

    Move related code together.

    Update module qualifications in C# and Java code.

    Delete the second #include of mercury_library_types.h.

    Delete the MR_{initial,final}_io_state macros.

library/MODULES_UNDOC:
library/library.m:
    List the new submodule as undocumented.

library/io.primitives_read.m:
library/io.primitives_write.m:
    Move the C, C# and Java code related to reading and writing values
    of primitive types here from io.m. Put them into one foreign_decl
    and one foreign_code per language.

    Update module qualifications in C# and Java code.

library/benchmarking.m:
library/bitmap.m:
library/io.call_system.m:
    Update module qualifications in C# and Java code.

library/stm_builtin.m:
    Replace uses of the MR_{initial,final}_io_state macros with their bodies.
This commit is contained in:
Zoltan Somogyi
2022-03-14 15:20:22 +11:00
parent bd60012ff2
commit 05fd615471
10 changed files with 2239 additions and 2204 deletions

View File

@@ -2,6 +2,7 @@ backjump.m
io.primitives_read.m
io.primitives_write.m
io.stream_db.m
io.stream_ops.m
mer_std.m
mutvar.m
par_builtin.m

View File

@@ -302,7 +302,7 @@ report_standard_stats(!IO) :-
"
try {
jmercury.benchmarking.ML_report_standard_stats(
(jmercury.io.MR_TextOutputFile) Stream);
(jmercury.io__stream_ops.MR_TextOutputFile) Stream);
Error = null;
} catch (java.io.IOException e) {
Error = e;
@@ -350,7 +350,7 @@ report_full_memory_stats(!IO) :-
"
try {
jmercury.benchmarking.ML_report_full_memory_stats(
(jmercury.io.MR_TextOutputFile) Stream);
(jmercury.io__stream_ops.MR_TextOutputFile) Stream);
Error = null;
} catch (java.io.IOException e) {
Error = e;
@@ -432,6 +432,10 @@ report_full_memory_stats :-
%---------------------------------------------------------------------------%
:- pragma foreign_import_module("C#", io.primitives_write).
:- pragma foreign_import_module("C#", io.stream_ops).
:- pragma foreign_import_module("Java", io.stream_ops).
:- pragma foreign_code("C#",
"
private static double user_time_at_start
@@ -444,7 +448,7 @@ private static long real_time_at_start
private static long real_time_at_last_stat;
public static void
ML_report_standard_stats(io.MR_MercuryFileStruct stream)
ML_report_standard_stats(mercury.io__stream_ops.MR_MercuryFileStruct stream)
{
double user_time_at_prev_stat = user_time_at_last_stat;
user_time_at_last_stat = System.Diagnostics.Process.GetCurrentProcess()
@@ -453,26 +457,28 @@ ML_report_standard_stats(io.MR_MercuryFileStruct stream)
long real_time_at_prev_stat = real_time_at_last_stat;
real_time_at_last_stat = System.DateTime.Now.Ticks;
io.mercury_print_string(stream, System.String.Format(
""[User time: +{0:F2}s, {1:F2}s Real time: +{2:F2}s, {3:F2}s]\\n"",
(user_time_at_last_stat - user_time_at_prev_stat),
(user_time_at_last_stat - user_time_at_start),
((real_time_at_last_stat - real_time_at_prev_stat)
/ (double) System.TimeSpan.TicksPerSecond),
((real_time_at_last_stat - real_time_at_start)
/ (double) System.TimeSpan.TicksPerSecond)
));
mercury.io__primitives_write.mercury_print_string(stream,
System.String.Format(
""[User time: +{0:F2}s, {1:F2}s Real time: +{2:F2}s, {3:F2}s]\\n"",
(user_time_at_last_stat - user_time_at_prev_stat),
(user_time_at_last_stat - user_time_at_start),
((real_time_at_last_stat - real_time_at_prev_stat)
/ (double) System.TimeSpan.TicksPerSecond),
((real_time_at_last_stat - real_time_at_start)
/ (double) System.TimeSpan.TicksPerSecond)
)
);
// XXX At this point there should be a whole bunch of memory usage
// statistics.
}
public static void
ML_report_full_memory_stats(io.MR_MercuryFileStruct stream)
ML_report_full_memory_stats(mercury.io__stream_ops.MR_MercuryFileStruct stream)
{
// XXX The support for this predicate is even worse. Since we don't have
// access to memory usage statistics, all you get here is an apology.
// But at least it doesn't just crash with an error.
io.mercury_print_string(stream,
mercury.io__primitives_write.mercury_print_string(stream,
""Sorry, report_full_memory_stats is not yet "" +
""implemented for the C# back-end.\\n"");
}
@@ -496,7 +502,7 @@ ML_initialise()
}
public static void
ML_report_standard_stats(jmercury.io.MR_TextOutputFile stream)
ML_report_standard_stats(jmercury.io__stream_ops.MR_TextOutputFile stream)
throws java.io.IOException
{
int user_time_at_prev_stat = user_time_at_last_stat;
@@ -525,7 +531,7 @@ ML_report_standard_stats(jmercury.io.MR_TextOutputFile stream)
}
public static void
ML_report_full_memory_stats(jmercury.io.MR_TextOutputFile stream)
ML_report_full_memory_stats(jmercury.io__stream_ops.MR_TextOutputFile stream)
throws java.io.IOException
{
// XXX The support for this predicate is even worse. Since we don't have

View File

@@ -557,6 +557,9 @@
:- import_module require.
:- import_module string.
:- pragma foreign_import_module("C#", io.stream_ops).
:- pragma foreign_import_module("Java", io.stream_ops).
%---------------------------------------------------------------------------%
init(N, B) = BM :-
@@ -2015,7 +2018,7 @@ read_bitmap_range(InputStream, Start, NumBytes, !Bitmap,
Error::out, _IO0::di, _IO::uo),
[will_not_call_mercury, promise_pure, tabled_for_io, thread_safe],
"
io.MR_MercuryFileStruct mf = Stream;
mercury.io__stream_ops.MR_MercuryFileStruct mf = Stream;
Bitmap = Bitmap0;
BytesRead = BytesRead0;
@@ -2042,7 +2045,8 @@ read_bitmap_range(InputStream, Start, NumBytes, !Bitmap,
Error::out, _IO0::di, _IO::uo),
[will_not_call_mercury, promise_pure, tabled_for_io, thread_safe],
"
io.MR_BinaryInputFile mf = (io.MR_BinaryInputFile) Stream;
jmercury.io__stream_ops.MR_BinaryInputFile mf =
(jmercury.io__stream_ops.MR_BinaryInputFile) Stream;
Bitmap = Bitmap0;
BytesRead = BytesRead0;
@@ -2159,7 +2163,8 @@ write_bitmap_range(OutputStream, Bitmap, Start, NumBytes, !IO) :-
no_sharing],
"
try {
((io.MR_BinaryOutputFile) Stream).write(Bitmap.elements, Start, Length);
((jmercury.io__stream_ops.MR_BinaryOutputFile) Stream).write(
Bitmap.elements, Start, Length);
Error = null;
} catch (java.io.IOException e) {
Error = e;

View File

@@ -233,12 +233,13 @@ call_system_return_signal(Command, Result, !IO) :-
process = java.lang.Runtime.getRuntime().exec(Command);
}
StreamPipe stdin = new StreamPipe(jmercury.io.mercury_stdin,
StreamPipe stdin = new StreamPipe(
jmercury.io__stream_ops.mercury_stdin,
process.getOutputStream());
StreamPipe stdout = new StreamPipe(process.getInputStream(),
jmercury.io.mercury_stdout);
jmercury.io__stream_ops.mercury_stdout);
StreamPipe stderr = new StreamPipe(process.getErrorStream(),
jmercury.io.mercury_stderr);
jmercury.io__stream_ops.mercury_stderr);
stdin.start();
stdout.start();
stderr.start();
@@ -270,24 +271,27 @@ call_system_return_signal(Command, Result, !IO) :-
").
:- pragma foreign_code("Java", "
// StreamPipe is a mechanism for connecting streams to those of a
// Runtime.exec() Process.
private static class StreamPipe extends java.lang.Thread {
jmercury.io.MR_TextInputFile in;
jmercury.io.MR_TextOutputFile out;
jmercury.io__stream_ops.MR_TextInputFile in;
jmercury.io__stream_ops.MR_TextOutputFile out;
boolean closeOutput = false;
java.lang.Exception exception = null;
StreamPipe(java.io.InputStream in, jmercury.io.MR_TextOutputFile out) {
this.in = new jmercury.io.MR_TextInputFile(in);
StreamPipe(java.io.InputStream in,
jmercury.io__stream_ops.MR_TextOutputFile out)
{
this.in = new jmercury.io__stream_ops.MR_TextInputFile(in);
this.out = out;
}
StreamPipe(jmercury.io.MR_TextInputFile in, java.io.OutputStream out) {
StreamPipe(jmercury.io__stream_ops.MR_TextInputFile in,
java.io.OutputStream out)
{
this.in = in;
this.out = new jmercury.io.MR_TextOutputFile(out);
this.out = new jmercury.io__stream_ops.MR_TextOutputFile(out);
closeOutput = true;
}

File diff suppressed because it is too large Load Diff

View File

@@ -61,13 +61,6 @@
:- implementation.
:- pragma foreign_decl("C", "
#include ""mercury_types.h"" // for MR_Integer
#include ""mercury_int.h"" // for MR_*_reverse_bytes
#include <inttypes.h>
").
%---------------------------------------------------------------------------%
read_char_code(input_stream(Stream), ResultCode, Char, Error, !IO) :-
@@ -155,9 +148,9 @@ read_char_code(input_stream(Stream), ResultCode, Char, Error, !IO) :-
_IO0::di, _IO::uo),
[will_not_call_mercury, promise_pure],
"
io.MR_MercuryFileStruct mf = File;
mercury.io__stream_ops.MR_MercuryFileStruct mf = File;
try {
int c = io.mercury_getc(mf);
int c = mercury.io__primitives_read.mercury_getc(mf);
if (c == -1) {
ResultCode = io.ML_RESULT_CODE_EOF;
Char = 0;
@@ -179,7 +172,7 @@ read_char_code(input_stream(Stream), ResultCode, Char, Error, !IO) :-
[will_not_call_mercury, promise_pure, thread_safe, tabled_for_io],
"
try {
int c = ((io.MR_TextInputFile) File).read_char();
int c = ((jmercury.io__stream_ops.MR_TextInputFile) File).read_char();
if (c == -1) {
ResultCode = io.ML_RESULT_CODE_EOF;
CharCode = 0;
@@ -231,7 +224,7 @@ read_char_code(input_stream(Stream), ResultCode, Char, Error, !IO) :-
putback_char_2(File::in, Character::in, Ok::out, _IO0::di, _IO::uo),
[will_not_call_mercury, promise_pure],
"
io.MR_MercuryFileStruct mf = File;
mercury.io__stream_ops.MR_MercuryFileStruct mf = File;
if (mf.putback == -1) {
mf.putback = Character;
if (Character == '\\n') {
@@ -247,7 +240,7 @@ read_char_code(input_stream(Stream), ResultCode, Char, Error, !IO) :-
putback_char_2(File::in, Character::in, Ok::out, _IO0::di, _IO::uo),
[will_not_call_mercury, promise_pure, thread_safe, tabled_for_io],
"
((io.MR_TextInputFile) File).ungetc(Character);
((jmercury.io__stream_ops.MR_TextInputFile) File).ungetc(Character);
Ok = bool.YES;
").
@@ -287,7 +280,7 @@ read_byte_val(input_stream(Stream), Result, ByteVal, Error, !IO) :-
_IO0::di, _IO::uo),
[will_not_call_mercury, promise_pure],
"
io.MR_MercuryFileStruct mf = File;
mercury.io__stream_ops.MR_MercuryFileStruct mf = File;
if (mf.putback != -1) {
ResultCode = io.ML_RESULT_CODE_OK;
ByteVal = mf.putback;
@@ -318,7 +311,8 @@ read_byte_val(input_stream(Stream), Result, ByteVal, Error, !IO) :-
[will_not_call_mercury, promise_pure, thread_safe, tabled_for_io],
"
try {
int b = ((io.MR_BinaryInputFile) File).read_byte();
int b =
((jmercury.io__stream_ops.MR_BinaryInputFile) File).read_byte();
if (b == -1) {
ResultCode = io.ML_RESULT_CODE_EOF;
ByteVal = 0;
@@ -353,7 +347,7 @@ read_byte_val(input_stream(Stream), Result, ByteVal, Error, !IO) :-
putback_uint8_2(File::in, UInt8::in, Ok::out, _IO0::di, _IO::uo),
[will_not_call_mercury, promise_pure],
"
io.MR_MercuryFileStruct mf = File;
mercury.io__stream_ops.MR_MercuryFileStruct mf = File;
if (mf.putback == -1) {
mf.putback = UInt8;
Ok = mr_bool.YES;
@@ -366,7 +360,7 @@ read_byte_val(input_stream(Stream), Result, ByteVal, Error, !IO) :-
putback_uint8_2(File::in, UInt8::in, Ok::out, _IO0::di, _IO::uo),
[will_not_call_mercury, promise_pure, thread_safe, tabled_for_io],
"
((io.MR_BinaryInputFile) File).ungetc((byte) UInt8);
((jmercury.io__stream_ops.MR_BinaryInputFile) File).ungetc((byte) UInt8);
Ok = bool.YES;
").
@@ -388,7 +382,7 @@ read_byte_val(input_stream(Stream), Result, ByteVal, Error, !IO) :-
[will_not_call_mercury, promise_pure, thread_safe],
"
byte[] buffer = new byte[2];
io.MR_MercuryFileStruct mf = Stream;
mercury.io__stream_ops.MR_MercuryFileStruct mf = Stream;
UInt16 = 0;
IncompleteBytes = list.empty_list();
@@ -436,7 +430,8 @@ read_byte_val(input_stream(Stream), Result, ByteVal, Error, !IO) :-
[will_not_call_mercury, promise_pure, thread_safe],
"
byte[] buffer = new byte[2];
io.MR_BinaryInputFile mf = (io.MR_BinaryInputFile) Stream;
jmercury.io__stream_ops.MR_BinaryInputFile mf =
(jmercury.io__stream_ops.MR_BinaryInputFile) Stream;
UInt16 = 0;
IncompleteBytes = list.empty_list();
@@ -489,7 +484,7 @@ read_byte_val(input_stream(Stream), Result, ByteVal, Error, !IO) :-
[will_not_call_mercury, promise_pure, thread_safe],
"
byte[] buffer = new byte[4];
io.MR_MercuryFileStruct mf = Stream;
mercury.io__stream_ops.MR_MercuryFileStruct mf = Stream;
UInt32 = 0;
IncompleteBytes = list.empty_list();
@@ -547,7 +542,8 @@ read_byte_val(input_stream(Stream), Result, ByteVal, Error, !IO) :-
[will_not_call_mercury, promise_pure, thread_safe],
"
byte[] buffer = new byte[4];
io.MR_BinaryInputFile mf = (io.MR_BinaryInputFile) Stream;
jmercury.io__stream_ops.MR_BinaryInputFile mf =
(jmercury.io__stream_ops.MR_BinaryInputFile) Stream;
UInt32 = 0;
IncompleteBytes = list.empty_list();
@@ -610,7 +606,7 @@ read_byte_val(input_stream(Stream), Result, ByteVal, Error, !IO) :-
[will_not_call_mercury, promise_pure, thread_safe],
"
byte[] buffer = new byte[8];
io.MR_MercuryFileStruct mf = Stream;
mercury.io__stream_ops.MR_MercuryFileStruct mf = Stream;
UInt64 = 0;
IncompleteBytes = list.empty_list();
@@ -676,7 +672,8 @@ read_byte_val(input_stream(Stream), Result, ByteVal, Error, !IO) :-
[will_not_call_mercury, promise_pure, thread_safe],
"
byte[] buffer = new byte[8];
io.MR_BinaryInputFile mf = (io.MR_BinaryInputFile) Stream;
jmercury.io__stream_ops.MR_BinaryInputFile mf =
(jmercury.io__stream_ops.MR_BinaryInputFile) Stream;
UInt64 = 0;
IncompleteBytes = list.empty_list();
@@ -729,12 +726,36 @@ read_byte_val(input_stream(Stream), Result, ByteVal, Error, !IO) :-
}
").
%---------------------%
%
% C implementation of reading multibyte integers from binary streams.
%
%---------------------------------------------------------------------------%
:- pragma foreign_decl("C", "
#ifdef MR_HAVE_UNISTD_H
#include <unistd.h>
#endif
#include ""mercury_types.h"" // for MR_Integer
#include ""mercury_int.h"" // for MR_*_reverse_bytes
#include <inttypes.h>
#ifdef MR_WIN32
// This is for SSIZE_T.
#include ""mercury_windows.h""
#endif
#if defined(MR_MSVC)
typedef SSIZE_T ML_ssize_t;
#else
typedef ssize_t ML_ssize_t;
#endif
int mercury_get_byte(MercuryFilePtr mf);
///////////////////////////////////////////////////////////////////////////
//
// The C implementation of reading multibyte integers from binary streams.
//
// ML_N_BIT_UINT_T(n) expands to the name of an n-bit unsigned integer type
// in C, if N is 8, 16, 32 or 64.
//
@@ -832,6 +853,116 @@ read_byte_val(input_stream(Stream), Result, ByteVal, Error, !IO) :-
} while (0)
").
:- pragma foreign_code("C", "
int
mercury_get_byte(MercuryFilePtr mf)
{
int c = MR_GETCH(*mf);
if (c == '\\n') {
MR_line_number(*mf)++;
}
return c;
}
").
%---------------------------------------------------------------------------%
:- pragma foreign_import_module("C#", io.stream_ops).
:- pragma foreign_decl("C#", "
// XXX zs: I don't know which of these are needed.
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Security.AccessControl;
using System.Security.Principal;
").
:- pragma foreign_code("C#", "
// Read in a character. This means reading in one or more bytes,
// converting the bytes from the system's default encoding to Unicode,
// and possibly converting CR-LF to newline. Returns -1 on EOF, and
// throws an exception on error.
private static readonly string NewLine = System.Environment.NewLine;
public static int
mercury_getc(mercury.io__stream_ops.MR_MercuryFileStruct mf)
{
int c;
if (mf.putback != -1) {
c = mf.putback;
mf.putback = -1;
if (c == '\\n') {
mf.line_number++;
}
return c;
}
if (mf.reader == null) {
mf.reader = new System.IO.StreamReader(mf.stream,
mercury.io__stream_ops.text_encoding);
}
c = mf.reader.Read();
switch (mf.line_ending) {
case mercury.io__stream_ops.ML_line_ending_kind.ML_raw_binary:
case mercury.io__stream_ops.ML_line_ending_kind.ML_Unix_line_ending:
if (c == '\\n') {
mf.line_number++;
}
break;
case mercury.io__stream_ops.ML_line_ending_kind.ML_OS_line_ending:
// First, check if the character we have read matches
// System.Environment.NewLine.
// We assume that System.Environment.NewLine is non-null
// and that System.Environment.NewLine.Length > 0.
if (c != mercury.io__primitives_read.NewLine[0]) {
if (c == '\\n') {
// the input file was ill-formed, e.g. it contained only raw
// LFs rather than CR-LF. Perhaps we should throw an exception?
// If not, we still need to treat this as a newline, and thus
// increment the line counter.
mf.line_number++;
} else if (System.Char.IsSurrogate((char) c)) {
int c2 = mf.reader.Read();
c = System.Char.ConvertToUtf32((char) c, (char) c2);
}
} else /* c == NewLine[0] */ {
switch (mercury.io__primitives_read.NewLine.Length) {
case 1:
mf.line_number++;
c = '\\n';
break;
case 2:
if (mf.reader.Peek() ==
mercury.io__primitives_read.NewLine[1])
{
mf.reader.Read();
mf.line_number++;
c = '\\n';
} else if (c == '\\n') {
// the input file was ill-formed, e.g. it contained only
// raw CRs rather than CR-LF. Perhaps we should throw an
// exception? If not, we still need to treat this
// as a newline, and thus increment the line counter.
mf.line_number++;
}
break;
default:
runtime.Errors.SORRY(
""mercury_getc: Environment.NewLine.Length"" +
""is neither 1 nor 2"");
break;
}
}
break;
}
return c;
}
").
%---------------------------------------------------------------------------%
:- end_module io.primitives_read.
%---------------------------------------------------------------------------%

View File

@@ -96,13 +96,6 @@
:- implementation.
:- pragma foreign_decl("C", "
#include ""mercury_types.h"" // for MR_Integer
#include ""mercury_int.h"" // for MR_*_reverse_bytes
#include <inttypes.h>
").
%---------------------------------------------------------------------------%
:- pragma foreign_proc("C",
@@ -137,27 +130,28 @@
[will_not_call_mercury, promise_pure, thread_safe, tabled_for_io,
may_not_duplicate],
"
io.MR_MercuryFileStruct stream = Stream;
mercury.io__stream_ops.MR_MercuryFileStruct stream = Stream;
try {
// See mercury_print_string().
if (stream.writer == null) {
stream.writer = new System.IO.StreamWriter(stream.stream,
io.text_encoding);
mercury.io__stream_ops.text_encoding);
}
System.IO.TextWriter w = stream.writer;
if (Character == '\\n') {
switch (stream.line_ending) {
case io.ML_line_ending_kind.ML_raw_binary:
case io.ML_line_ending_kind.ML_Unix_line_ending:
mercury.io.mercury_write_codepoint(w, Character);
case mercury.io__stream_ops.ML_line_ending_kind.ML_raw_binary:
case mercury.io__stream_ops.ML_line_ending_kind.ML_Unix_line_ending:
mercury.io__primitives_write.mercury_write_codepoint(w,
Character);
break;
case io.ML_line_ending_kind.ML_OS_line_ending:
case mercury.io__stream_ops.ML_line_ending_kind.ML_OS_line_ending:
w.WriteLine("""");
break;
}
stream.line_number++;
} else {
mercury.io.mercury_write_codepoint(w, Character);
mercury.io__primitives_write.mercury_write_codepoint(w, Character);
}
Error = null;
} catch (System.SystemException e) {
@@ -172,7 +166,7 @@
try {
char[] buf = java.lang.Character.toChars(Character);
for (char c : buf) {
((io.MR_TextOutputFile) Stream).put(c);
((jmercury.io__stream_ops.MR_TextOutputFile) Stream).put(c);
}
Error = null;
} catch (java.io.IOException e) {
@@ -199,7 +193,8 @@
[will_not_call_mercury, promise_pure, thread_safe, tabled_for_io],
"
try {
io.mercury_print_string(Stream, Val.ToString());
mercury.io__primitives_write.mercury_print_string(Stream,
Val.ToString());
Error = null;
} catch (System.SystemException e) {
Error = e;
@@ -211,7 +206,8 @@
[will_not_call_mercury, promise_pure, tabled_for_io, thread_safe],
"
try {
((io.MR_TextOutputFile) Stream).write(String.valueOf(Val));
((jmercury.io__stream_ops.MR_TextOutputFile) Stream).write(
String.valueOf(Val));
Error = null;
} catch (java.io.IOException e) {
Error = e;
@@ -237,7 +233,8 @@
[will_not_call_mercury, promise_pure, thread_safe, tabled_for_io],
"
try {
io.mercury_print_string(Stream, Val.ToString());
mercury.io__primitives_write.mercury_print_string(Stream,
Val.ToString());
Error = null;
} catch (System.SystemException e) {
Error = e;
@@ -249,7 +246,7 @@
[will_not_call_mercury, promise_pure, tabled_for_io, thread_safe],
"
try {
((io.MR_TextOutputFile) Stream).write(
((jmercury.io__stream_ops.MR_TextOutputFile) Stream).write(
java.lang.Long.toString(Val & 0xffffffffL));
Error = null;
} catch (java.io.IOException e) {
@@ -276,7 +273,8 @@
[will_not_call_mercury, promise_pure, thread_safe, tabled_for_io],
"
try {
io.mercury_print_string(Stream, Val.ToString());
mercury.io__primitives_write.mercury_print_string(Stream,
Val.ToString());
Error = null;
} catch (System.SystemException e) {
Error = e;
@@ -288,7 +286,8 @@
[will_not_call_mercury, promise_pure, tabled_for_io, thread_safe],
"
try {
((io.MR_TextOutputFile) Stream).write(String.valueOf(Val));
((jmercury.io__stream_ops.MR_TextOutputFile) Stream).write(
String.valueOf(Val));
Error = null;
} catch (java.io.IOException e) {
Error = e;
@@ -314,7 +313,8 @@
[will_not_call_mercury, promise_pure, thread_safe, tabled_for_io],
"
try {
io.mercury_print_string(Stream, Val.ToString());
mercury.io__primitives_write.mercury_print_string(Stream,
Val.ToString());
Error = null;
} catch (System.SystemException e) {
Error = e;
@@ -326,7 +326,7 @@
[will_not_call_mercury, promise_pure, tabled_for_io, thread_safe],
"
try {
((io.MR_TextOutputFile) Stream).write(
((jmercury.io__stream_ops.MR_TextOutputFile) Stream).write(
java.lang.Integer.toString(Val & 0xff));
Error = null;
} catch (java.io.IOException e) {
@@ -353,7 +353,8 @@
[will_not_call_mercury, promise_pure, thread_safe, tabled_for_io],
"
try {
io.mercury_print_string(Stream, Val.ToString());
mercury.io__primitives_write.mercury_print_string(Stream,
Val.ToString());
Error = null;
} catch (System.SystemException e) {
Error = e;
@@ -365,7 +366,8 @@
[will_not_call_mercury, promise_pure, tabled_for_io, thread_safe],
"
try {
((io.MR_TextOutputFile) Stream).write(String.valueOf(Val));
((jmercury.io__stream_ops.MR_TextOutputFile) Stream).write(
String.valueOf(Val));
Error = null;
} catch (java.io.IOException e) {
Error = e;
@@ -391,7 +393,8 @@
[will_not_call_mercury, promise_pure, thread_safe, tabled_for_io],
"
try {
io.mercury_print_string(Stream, Val.ToString());
mercury.io__primitives_write.mercury_print_string(Stream,
Val.ToString());
Error = null;
} catch (System.SystemException e) {
Error = e;
@@ -403,7 +406,7 @@
[will_not_call_mercury, promise_pure, tabled_for_io, thread_safe],
"
try {
((io.MR_TextOutputFile) Stream).write(
((jmercury.io__stream_ops.MR_TextOutputFile) Stream).write(
java.lang.Integer.toString(Val & 0xffff));
Error = null;
} catch (java.io.IOException e) {
@@ -430,7 +433,8 @@
[will_not_call_mercury, promise_pure, thread_safe, tabled_for_io],
"
try {
io.mercury_print_string(Stream, Val.ToString());
mercury.io__primitives_write.mercury_print_string(Stream,
Val.ToString());
Error = null;
} catch (System.SystemException e) {
Error = e;
@@ -442,7 +446,8 @@
[will_not_call_mercury, promise_pure, tabled_for_io, thread_safe],
"
try {
((io.MR_TextOutputFile) Stream).write(String.valueOf(Val));
((jmercury.io__stream_ops.MR_TextOutputFile) Stream).write(
String.valueOf(Val));
Error = null;
} catch (java.io.IOException e) {
Error = e;
@@ -468,7 +473,8 @@
[will_not_call_mercury, promise_pure, thread_safe, tabled_for_io],
"
try {
io.mercury_print_string(Stream, Val.ToString());
mercury.io__primitives_write.mercury_print_string(Stream,
Val.ToString());
Error = null;
} catch (System.SystemException e) {
Error = e;
@@ -480,7 +486,7 @@
[will_not_call_mercury, promise_pure, tabled_for_io, thread_safe],
"
try {
((io.MR_TextOutputFile) Stream).write(
((jmercury.io__stream_ops.MR_TextOutputFile) Stream).write(
java.lang.Long.toString(Val & 0xffffffffL));
Error = null;
} catch (java.io.IOException e) {
@@ -507,7 +513,8 @@
[will_not_call_mercury, promise_pure, thread_safe, tabled_for_io],
"
try {
io.mercury_print_string(Stream, Val.ToString());
mercury.io__primitives_write.mercury_print_string(Stream,
Val.ToString());
Error = null;
} catch (System.SystemException e) {
Error = e;
@@ -519,7 +526,8 @@
[will_not_call_mercury, promise_pure, tabled_for_io, thread_safe],
"
try {
((io.MR_TextOutputFile) Stream).write(String.valueOf(Val));
((jmercury.io__stream_ops.MR_TextOutputFile) Stream).write(
String.valueOf(Val));
Error = null;
} catch (java.io.IOException e) {
Error = e;
@@ -545,7 +553,8 @@
[will_not_call_mercury, promise_pure, thread_safe, tabled_for_io],
"
try {
io.mercury_print_string(Stream, Val.ToString());
mercury.io__primitives_write.mercury_print_string(Stream,
Val.ToString());
Error = null;
} catch (System.SystemException e) {
Error = e;
@@ -557,7 +566,7 @@
[will_not_call_mercury, promise_pure, tabled_for_io, thread_safe],
"
try {
((io.MR_TextOutputFile) Stream).write(
((jmercury.io__stream_ops.MR_TextOutputFile) Stream).write(
java.lang.Long.toUnsignedString(Val));
Error = null;
} catch (java.io.IOException e) {
@@ -587,7 +596,8 @@
do_write_float(Stream::in, Val::in, Error::out, _IO0::di, _IO::uo),
[will_not_call_mercury, promise_pure, tabled_for_io, thread_safe],
"
io.MR_TextOutputFile stream = (io.MR_TextOutputFile) Stream;
jmercury.io__stream_ops.MR_TextOutputFile stream =
(jmercury.io__stream_ops.MR_TextOutputFile) Stream;
try {
if (Double.isNaN(Val)) {
@@ -635,7 +645,7 @@ do_write_float(Stream, Float, Error, !IO) :-
[will_not_call_mercury, promise_pure, thread_safe, tabled_for_io],
"
try {
io.mercury_print_string(Stream, Message);
mercury.io__primitives_write.mercury_print_string(Stream, Message);
Error = null;
} catch (System.SystemException e) {
Error = e;
@@ -647,7 +657,7 @@ do_write_float(Stream, Float, Error, !IO) :-
[will_not_call_mercury, promise_pure, thread_safe, tabled_for_io],
"
try {
((io.MR_TextOutputFile) Stream).write(Message);
((jmercury.io__stream_ops.MR_TextOutputFile) Stream).write(Message);
Error = null;
} catch (java.io.IOException e) {
Error = e;
@@ -686,7 +696,8 @@ do_write_float(Stream, Float, Error, !IO) :-
[will_not_call_mercury, promise_pure, thread_safe, tabled_for_io],
"
try {
((io.MR_BinaryOutputFile) Stream).put((byte) Byte);
((jmercury.io__stream_ops.MR_BinaryOutputFile) Stream).put(
(byte) Byte);
Error = null;
} catch (java.io.IOException e) {
Error = e;
@@ -714,7 +725,8 @@ do_write_float(Stream, Float, Error, !IO) :-
java.nio.ByteBuffer buffer = java.nio.ByteBuffer.allocate(2);
buffer.order(java.nio.ByteOrder.nativeOrder());
buffer.putShort(U16);
((io.MR_BinaryOutputFile) Stream).write(buffer.array(), 0, 2);
((jmercury.io__stream_ops.MR_BinaryOutputFile) Stream).write(
buffer.array(), 0, 2);
Error = null;
} catch (java.io.IOException e) {
Error = e;
@@ -778,7 +790,8 @@ do_write_float(Stream, Float, Error, !IO) :-
java.nio.ByteBuffer buffer = java.nio.ByteBuffer.allocate(2);
buffer.order(java.nio.ByteOrder.LITTLE_ENDIAN);
buffer.putShort(U16);
((io.MR_BinaryOutputFile) Stream).write(buffer.array(), 0, 2);
((jmercury.io__stream_ops.MR_BinaryOutputFile) Stream).write(
buffer.array(), 0, 2);
Error = null;
} catch (java.io.IOException e) {
Error = e;
@@ -829,7 +842,8 @@ do_write_float(Stream, Float, Error, !IO) :-
java.nio.ByteBuffer buffer = java.nio.ByteBuffer.allocate(2);
// Order in a byte buffer is big endian by default.
buffer.putShort(U16);
((io.MR_BinaryOutputFile) Stream).write(buffer.array(), 0, 2);
((jmercury.io__stream_ops.MR_BinaryOutputFile) Stream).write(
buffer.array(), 0, 2);
Error = null;
} catch (java.io.IOException e) {
Error = e;
@@ -872,7 +886,8 @@ do_write_float(Stream, Float, Error, !IO) :-
java.nio.ByteBuffer buffer = java.nio.ByteBuffer.allocate(4);
buffer.order(java.nio.ByteOrder.nativeOrder());
buffer.putInt(U32);
((io.MR_BinaryOutputFile) Stream).write(buffer.array(), 0, 4);
((jmercury.io__stream_ops.MR_BinaryOutputFile) Stream).write(
buffer.array(), 0, 4);
Error = null;
} catch (java.io.IOException e) {
Error = e;
@@ -923,7 +938,8 @@ do_write_float(Stream, Float, Error, !IO) :-
java.nio.ByteBuffer buffer = java.nio.ByteBuffer.allocate(4);
buffer.order(java.nio.ByteOrder.LITTLE_ENDIAN);
buffer.putInt(U32);
((io.MR_BinaryOutputFile) Stream).write(buffer.array(), 0, 4);
((jmercury.io__stream_ops.MR_BinaryOutputFile) Stream).write(
buffer.array(), 0, 4);
Error = null;
} catch (java.io.IOException e) {
Error = e;
@@ -974,7 +990,8 @@ do_write_float(Stream, Float, Error, !IO) :-
java.nio.ByteBuffer buffer = java.nio.ByteBuffer.allocate(4);
// Order in a byte buffer is big endian by default.
buffer.putInt(U32);
((io.MR_BinaryOutputFile) Stream).write(buffer.array(), 0, 4);
((jmercury.io__stream_ops.MR_BinaryOutputFile) Stream).write(
buffer.array(), 0, 4);
Error = null;
} catch (java.io.IOException e) {
Error = e;
@@ -1017,7 +1034,8 @@ do_write_float(Stream, Float, Error, !IO) :-
java.nio.ByteBuffer buffer = java.nio.ByteBuffer.allocate(8);
buffer.order(java.nio.ByteOrder.nativeOrder());
buffer.putLong(U64);
((io.MR_BinaryOutputFile) Stream).write(buffer.array(), 0, 8);
((jmercury.io__stream_ops.MR_BinaryOutputFile) Stream).write(
buffer.array(), 0, 8);
Error = null;
} catch (java.io.IOException e) {
Error = e;
@@ -1068,7 +1086,8 @@ do_write_float(Stream, Float, Error, !IO) :-
java.nio.ByteBuffer buffer = java.nio.ByteBuffer.allocate(8);
buffer.order(java.nio.ByteOrder.LITTLE_ENDIAN);
buffer.putLong(U64);
((io.MR_BinaryOutputFile) Stream).write(buffer.array(), 0, 8);
((jmercury.io__stream_ops.MR_BinaryOutputFile) Stream).write(
buffer.array(), 0, 8);
Error = null;
} catch (java.io.IOException e) {
Error = e;
@@ -1119,13 +1138,115 @@ do_write_float(Stream, Float, Error, !IO) :-
java.nio.ByteBuffer buffer = java.nio.ByteBuffer.allocate(8);
// Order in a byte buffer is big endian by default.
buffer.putLong(U64);
((io.MR_BinaryOutputFile) Stream).write(buffer.array(), 0, 8);
((jmercury.io__stream_ops.MR_BinaryOutputFile) Stream).write(
buffer.array(), 0, 8);
Error = null;
} catch (java.io.IOException e) {
Error = e;
}
").
%---------------------------------------------------------------------------%
%---------------------------------------------------------------------------%
:- pragma foreign_decl("C", "
// XXX zs: I don't know which other #includes from io.m, if any,
// we should have here to make the C code for this module self-contained.
#include ""mercury_types.h"" // for MR_Integer
#include ""mercury_library_types.h"" // for MercuryFilePtr, MR_PUTCH etc
#include ""mercury_int.h"" // for MR_*_reverse_bytes
#include <stdio.h>
#include <stdarg.h>
#include <inttypes.h>
int ML_fprintf(MercuryFilePtr mf, const char *format, ...);
").
:- pragma foreign_code("C", "
int
ML_fprintf(MercuryFilePtr mf, const char *format, ...)
{
int rc;
va_list args;
va_start(args, format);
rc = MR_VFPRINTF(*mf, format, args);
va_end(args);
return rc;
}
").
%---------------------------------------------------------------------------%
:- pragma foreign_import_module("C#", io.stream_ops).
:- pragma foreign_decl("C#", "
// XXX zs: I don't know which of these are needed.
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Security.AccessControl;
using System.Security.Principal;
").
:- pragma foreign_code("C#", "
public static void
mercury_write_codepoint(System.IO.TextWriter w, int c)
{
if (c <= 0xffff) {
w.Write((char) c);
} else {
w.Write(System.Char.ConvertFromUtf32(c));
}
}
// Any changes here should also be reflected in the code for io.write_char,
// which (for efficiency) uses its own inline code, rather than calling
// this function.
public static void
mercury_print_string(mercury.io__stream_ops.MR_MercuryFileStruct mf, string s)
{
if (mf.writer == null) {
mf.writer = new System.IO.StreamWriter(mf.stream,
mercury.io__stream_ops.text_encoding);
}
switch (mf.line_ending) {
case mercury.io__stream_ops.ML_line_ending_kind.ML_raw_binary:
case mercury.io__stream_ops.ML_line_ending_kind.ML_Unix_line_ending:
mf.writer.Write(s);
for (int i = 0; i < s.Length; i++) {
if (s[i] == '\\n') {
mf.line_number++;
}
}
break;
case mercury.io__stream_ops.ML_line_ending_kind.ML_OS_line_ending:
// We can't just use the System.TextWriter.Write(String) method,
// since that method doesn't convert newline characters to the
// system's newline convention (e.g. CR-LF on Windows).
// Only the WriteLine(...) method handles those properly.
// So we have to output each character separately.
for (int i = 0; i < s.Length; i++) {
if (System.Char.IsSurrogate(s[i])) {
mf.writer.Write(s.Substring(i, 2));
i++;
} else if (s[i] == '\\n') {
mf.line_number++;
mf.writer.WriteLine("""");
} else {
mf.writer.Write(s[i]);
}
}
break;
}
}
").
%---------------------------------------------------------------------------%
:- end_module io.primitives_write.
%---------------------------------------------------------------------------%

1817
library/io.stream_ops.m Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -123,7 +123,10 @@
:- import_module io.call_system.
:- import_module io.environment.
:- import_module io.file.
:- import_module io.primitives_read.
:- import_module io.primitives_write.
:- import_module io.stream_db.
:- import_module io.stream_ops.
:- import_module kv_list.
:- import_module lazy.
:- import_module list.
@@ -300,6 +303,7 @@ stdlib_module_doc_undoc("io.file", doc).
stdlib_module_doc_undoc("io.primitives_read", undoc).
stdlib_module_doc_undoc("io.primitives_write", undoc).
stdlib_module_doc_undoc("io.stream_db", undoc).
stdlib_module_doc_undoc("io.stream_ops", undoc).
stdlib_module_doc_undoc("kv_list", doc).
stdlib_module_doc_undoc("lazy", doc).
stdlib_module_doc_undoc("library", doc).

View File

@@ -354,7 +354,7 @@
[promise_pure, will_not_call_mercury, thread_safe],
"
STM = NULL;
MR_final_io_state(IO);
// ignore IO
").
:- pragma foreign_proc("C",
@@ -362,7 +362,7 @@
[promise_pure, will_not_call_mercury, thread_safe],
"
STM0 = NULL;
IO = MR_initial_io_state();
IO = 0; // The value does not matter.
").
%---------------------------------------------------------------------------%