[m-rev.] For review: Java implementation of IO library
James Goddard
goddardjames at yahoo.com
Thu Jan 8 15:04:41 AEDT 2004
Apologies in advance for the huge post (and doubtless quantity of mistakes) =)
Estimated hours taken: 60
Branches: main
Implement some library procedures for the Java back end.
library/io.m:
Implement the following procedures:
io__clear_err/3
ferror/5
io__get_system_error/3
make_err_message/5
io__stream_file_size/4
io__file_modification_time_2/6
file_type_implemented/0
io__file_type_2/5
io__check_file_accessibility_2/5
compare_file_id_2/6
io__get_stream_db/3
io__set_stream_db/3
io__get_globals/3
io__set_globals/3
io__get_stream_id/1
io__read_char_code/4
io__read_byte_val/4
io__putback_char/4
io__putback_byte/4
io__write_byte/3
io__write_bytes/3
io__flush_output/2
io__flush_binary_output/2
io__seek_binary_2/5
io__binary_stream_offset/4
io__write_string/4
io__write_char/4
io__write_int/4
io__write_float/4
io__write_byte/4
io__write_bytes/4
io__flush_output/3
io__flush_binary_output/3
io__stdin_stream/3
io__stdout_stream/3
io__stderr_stream/3
io__stdin_binary_stream/3
io__stdout_binary_stream/3
io__input_stream/3
io__output_stream/3
io__binary_input_stream/3
io__binary_output_stream/3
io__get_line_number/3
io__get_line_number/4
io__set_line_number/3
io__set_line_number/4
io__get_output_line_number/3
io__get_output_line_number/4
io__set_output_line_number/3
io__set_output_line_number/4
io__set_input_stream/4
io__set_output_stream/4
io__set_binary_input_stream/4
io__set_binary_output_stream/4
io__do_open_text/7
io__do_open_binary/7
io__close_stream/3
io__progname/4
io__get_exit_status/3
io__set_exit_status/3
build_command_line_args/2
command_line_argument/2
io__call_system_code/5
io__getenv/2
io__setenv/2
io__putenv/2
io__do_make_temp/8
io__make_temp/3
io__make_temp/5
io__remove_file_2/5
io__rename_file_2/6
io__make_symlink_2/5
io__read_symlink_2/6
Index: io.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/io.m,v
retrieving revision 1.315
diff -u -d -r1.315 io.m
--- io.m 2 Dec 2003 10:02:05 -0000 1.315
+++ io.m 8 Jan 2004 03:13:36 -0000
@@ -1654,6 +1654,12 @@
ML_file_encoding_kind.ML_OS_text_encoding;
").
+:- pragma foreign_code("Java",
+"
+ static java.lang.Object ML_io_stream_db;
+ static java.lang.Object ML_io_user_globals;
+").
+
:- type io__stream_putback == map(io__stream_id, list(char)).
@@ -1666,6 +1672,7 @@
:- pragma foreign_type("C", io__stream, "MercuryFilePtr").
:- pragma foreign_type("il", io__stream,
"class [mercury]mercury.io__csharp_code.MR_MercuryFileStruct").
+:- pragma foreign_type("Java", io__stream, "mercury.io.MR_MercuryFileStruct").
% a unique identifier for an IO stream
:- type io__stream_id == int.
@@ -2164,6 +2171,12 @@
// in MF_Mercury_file for compatibility)
}").
+:- pragma foreign_proc("Java",
+ io__clear_err(_Stream::in, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ // XXX as for .NET above
+").
:- pred io__check_err(stream, io__res, io__state, io__state).
:- mode io__check_err(in, out, di, uo) is det.
@@ -2203,6 +2216,14 @@
RetVal = 0;
}").
+:- pragma foreign_proc("Java",
+ ferror(_Stream::in, RetVal::out, _RetStr::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"{
+ // XXX see clearerr
+ RetVal = 0;
+}").
+
:- pred io__make_err_msg(string, string, io__state, io__state).
:- mode io__make_err_msg(in, out, di, uo) is det.
@@ -2228,6 +2249,13 @@
Error = MR_io_exception;
}").
+:- pragma foreign_proc("Java",
+ io__get_system_error(Error::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io, thread_safe],
+"{
+ Error = MR_io_exception;
+}").
+
:- pragma export(make_err_msg(in, in, out, di, uo), "ML_make_err_msg").
:- pragma foreign_proc("C",
make_err_msg(Error::in, Msg0::in, Msg::out, IO0::di, IO::uo),
@@ -2244,6 +2272,17 @@
Msg = System.String.Concat(Msg0, Error.Message);
}").
+:- pragma foreign_proc("Java",
+ make_err_msg(Error::in, Msg0::in, Msg::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure],
+"{
+ if (Error.getMessage() != null) {
+ Msg = Msg0 + Error.getMessage();
+ } else {
+ Msg = Msg0;
+ }
+}").
+
have_win32 :- semidet_fail.
:- pragma foreign_proc("C",
@@ -2353,6 +2392,13 @@
}
}").
+:- pragma foreign_proc("Java",
+ io__stream_file_size(Stream::in, Size::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ Size = Stream.size();
+").
+
io__file_modification_time(File, Result) -->
io__file_modification_time_2(File, Status, Msg, Time),
{ Status = 1 ->
@@ -2407,6 +2453,24 @@
}
}").
+:- pragma foreign_proc("Java",
+ io__file_modification_time_2(FileName::in, Status::out, Msg::out,
+ Time::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io, thread_safe],
+"
+ Time = new java.util.Date();
+
+ try {
+ ((java.util.Date) Time).setTime(
+ (new java.io.File(FileName)).lastModified());
+ Msg = """";
+ Status = 1;
+ } catch (java.lang.Exception e) {
+ ((java.util.Date) Time).setTime(0);
+ Msg = ""lastModified() failed: "" + e.getMessage();
+ Status = 0;
+ }
+").
%-----------------------------------------------------------------------------%
@@ -2436,6 +2500,11 @@
[will_not_call_mercury, promise_pure, thread_safe],
"SUCCESS_INDICATOR = true;"
).
+:- pragma foreign_proc("Java", file_type_implemented,
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ succeeded = true;
+").
:- pred io__file_type_2(int, string, io__res(io__file_type),
io__state, io__state).
@@ -2605,6 +2674,28 @@
}
").
+:- pragma foreign_proc("Java",
+ io__file_type_2(_FollowSymLinks::in, FileName::in,
+ Result::out, _IO0::di, _IO::uo),
+ [may_call_mercury, promise_pure, tabled_for_io, thread_safe],
+"
+ java.io.File file = new java.io.File(FileName);
+
+ // The Java implementation can distinguish between regular files and
+ // directorys, and for everything else it just returns unknown.
+
+ if (file.isFile()) {
+ Result = new mercury.io.res_1.ok_1(new mercury.io.file_type_0(
+ mercury.io.file_type_0.regular_file));
+ } else if (file.isDirectory()) {
+ Result = new mercury.io.res_1.ok_1(new mercury.io.file_type_0(
+ mercury.io.file_type_0.directory));
+ } else {
+ Result = new mercury.io.res_1.ok_1(new mercury.io.file_type_0(
+ mercury.io.file_type_0.unknown));
+ }
+").
+
:- func file_type_character_device = file_type.
:- func file_type_block_device = file_type.
:- func file_type_fifo = file_type.
@@ -2707,6 +2798,52 @@
IO = IO0;
}").
+:- pragma foreign_proc("Java",
+ io__check_file_accessibility_2(FileName::in, AccessTypes::in,
+ Result::out, _IO0::di, _IO::uo),
+ [may_call_mercury, promise_pure, tabled_for_io, thread_safe],
+"
+ java.lang.String permissions = null;
+
+ if (access_types_includes_read_1_p_0(
+ (mercury.list.list_1) AccessTypes))
+ {
+ permissions = ""read"";
+ }
+
+ if (access_types_includes_write_1_p_0(
+ (mercury.list.list_1) AccessTypes))
+ {
+ if (permissions == null) {
+ permissions = ""write"";
+ } else {
+ permissions = ""read,write"";
+ }
+ }
+
+ if (access_types_includes_execute_1_p_0(
+ (mercury.list.list_1) AccessTypes))
+ {
+ if (permissions == null) {
+ permissions = ""execute"";
+ } else {
+ permissions = permissions + "",execute"";
+ }
+ }
+
+ try {
+ if (permissions != null) {
+ java.lang.System.getSecurityManager().checkPermission(
+ new java.io.FilePermission(
+ FileName, permissions));
+ }
+ Result = make_io_res_0_ok_0_f_0();
+ }
+ catch (java.lang.Exception e) {
+ Result = make_io_res_0_error_msg_1_f_0(e.getMessage());
+ }
+").
+
% The .NET CLI doesn't provide an equivalent of access(), so
% we have to try to open the file to see if it is accessible.
:- pred io__check_file_accessibility_dotnet(string::in, list(access_type)::in,
@@ -2962,6 +3099,14 @@
}
").
+:- pragma foreign_proc("Java",
+ compare_file_id_2(_Res::out, _FileId1::in, _FileId2::in),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ throw new java.lang.RuntimeException(
+ ""File IDs are not supported by Java."");
+").
+
io__file_id(FileName, Result) -->
( { have_file_ids } ->
io__file_id_2(FileName, Status, Msg, FileId),
@@ -3001,6 +3146,19 @@
#endif
}").
+:- pragma foreign_proc("Java",
+ io__file_id_2(_FileName::in, _Status::out, _Msg::out,
+ _FileId::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io, thread_safe],
+"
+ // This function should never be called, since have_file_ids will
+ // fail for Java.
+ if (true) { // otherwise Java complains about unreachable stmts.
+ throw new RuntimeException(
+ ""io.file_id_2 called but not supported"");
+ }
+").
+
% Can we retrieve inode numbers on this system.
have_file_ids :- semidet_fail.
:- pragma foreign_proc("C", have_file_ids,
@@ -4199,6 +4357,20 @@
ML_io_stream_db = StreamDb;
").
+:- pragma foreign_proc("Java",
+ io__get_stream_db(StreamDb::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io],
+"
+ StreamDb = ML_io_stream_db;
+").
+
+:- pragma foreign_proc("Java",
+ io__set_stream_db(StreamDb::in, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io],
+"
+ ML_io_stream_db = StreamDb;
+").
+
%-----------------------------------------------------------------------------%
:- pred io__insert_stream_info(io__stream::in, stream_info::in,
@@ -4282,6 +4454,20 @@
ML_io_user_globals = Globals;
").
+:- pragma foreign_proc("Java",
+ io__get_globals(Globals::uo, _IOState0::di, _IOState::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io],
+"
+ Globals = ML_io_user_globals;
+").
+
+:- pragma foreign_proc("Java",
+ io__set_globals(Globals::di, _IOState0::di, _IOState::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io],
+"
+ ML_io_user_globals = Globals;
+").
+
io__progname_base(DefaultName, PrognameBase) -->
io__progname(DefaultName, Progname),
{ PrognameBase = dir__basename_det(Progname) }.
@@ -4314,6 +4500,13 @@
Id = Stream.id;
").
+:- pragma foreign_proc("Java",
+ io__get_stream_id(Stream::in) = (Id::out),
+ [will_not_call_mercury, promise_pure],
+"
+ Id = Stream.id;
+").
+
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
@@ -4603,6 +4796,257 @@
}
").
+:- pragma foreign_code("Java",
+"
+ /* stdin, stdout, stderr treated as input/output streams,
+ ** all files to use random access r+w
+ */
+ public static class MR_MercuryFileStruct {
+ public static int ML_next_stream_id = 0;
+ public int id;
+
+ public int line_number;
+
+ private static final int INPUT = 1;
+ private static final int OUTPUT = 2;
+ private static final int BOTH = 3;
+ private int mode;
+
+ private static final int SEEK_SET = 0;
+ private static final int SEEK_CUR = 1;
+ private static final int SEEK_END = 2;
+
+ private java.util.Stack pushback;
+ private java.io.InputStream input = null;
+ private java.io.OutputStream output = null;
+ private java.io.RandomAccessFile randomaccess = null;
+
+ private java.lang.String filename = null;
+
+ public MR_MercuryFileStruct(java.io.InputStream stream) {
+ line_number = 1;
+ id = ML_next_stream_id++;
+ mode = INPUT;
+ pushback = new java.util.Stack();
+ input = stream;
+ }
+
+ public MR_MercuryFileStruct(java.io.OutputStream stream) {
+ line_number = 1;
+ id = ML_next_stream_id++;
+ mode = OUTPUT;
+ pushback = null;
+ output = stream;
+ }
+
+ public MR_MercuryFileStruct(java.lang.String file) {
+ try {
+ randomaccess = new java.io.RandomAccessFile(
+ file, ""rws"");
+ } catch (java.lang.Exception e) {
+ throw new RuntimeException(e.getMessage());
+ }
+ line_number = 1;
+ id = ML_next_stream_id++;
+ mode = BOTH;
+ pushback = new java.util.Stack();
+ filename = file;
+ }
+
+ public MR_MercuryFileStruct(java.lang.String file,
+ boolean append)
+ {
+ try {
+ randomaccess = new java.io.RandomAccessFile(
+ file, ""rws"");
+ id = ML_next_stream_id++;
+ mode = BOTH;
+ pushback = new java.util.Stack();
+ filename = file;
+ line_number = 1;
+
+ if (append) {
+ while (true) {
+ int c = randomaccess.read();
+ if (c == '\\n') {
+ line_number++;
+ } else if (c == -1) {
+ break;
+ }
+ }
+ // XXX hopefully at this point we're at the
+ // end of the file, ready to append.
+ }
+ } catch (java.lang.Exception e) {
+ throw new RuntimeException(e.getMessage());
+ }
+ }
+
+ public int size() {
+ try {
+ return (int) randomaccess.length();
+ } catch (java.lang.Exception e) {
+ return -1;
+ }
+ }
+
+ public void seek(int flag, int offset) {
+ try {
+ switch (flag) {
+ case SEEK_SET:
+ randomaccess.seek(offset);
+ break;
+ case SEEK_CUR:
+ randomaccess.seek(
+ randomaccess.
+ getFilePointer() +
+ offset);
+ break;
+ case SEEK_END:
+ randomaccess.seek(
+ randomaccess.length() +
+ offset);
+ break;
+ default:
+ throw new java.lang.
+ RuntimeException(
+ ""Invalid seek flag"");
+ }
+ } catch (java.lang.Exception e) {
+ throw new java.lang.RuntimeException(
+ e.getMessage());
+ }
+ }
+
+ public int getOffset() {
+ try {
+ return (int) randomaccess.getFilePointer();
+ } catch (java.lang.Exception e) {
+ return -1;
+ }
+ }
+
+ public int getc() {
+ int c;
+ if (mode == OUTPUT) {
+ throw new java.lang.RuntimeException(
+ ""Attempted to read output stream"");
+ }
+ if (pushback.empty()) {
+ try {
+ if (input != null) {
+ c = input.read();
+ } else {
+ c = randomaccess.read();
+ }
+ } catch (java.io.IOException e) {
+ throw new java.lang.RuntimeException(
+ e.getMessage());
+ }
+ } else {
+ c = ((java.lang.Integer)pushback.pop()).
+ intValue();
+ }
+ if (c == '\\n') {
+ line_number++;
+ }
+
+ return c;
+ }
+
+ public void ungetc(int c) {
+ if (mode == OUTPUT) {
+ throw new java.lang.RuntimeException(
+ ""Attempted to unget char to output stream"");
+ }
+ if (c == '\\n') {
+ line_number--;
+ }
+
+ pushback.push(new Integer(c));
+ }
+
+ public void putc(int c) {
+ if (mode == INPUT) {
+ throw new java.lang.RuntimeException(
+ ""Attempted to write to input stream"");
+ }
+ if (c == '\\n') {
+ line_number++;
+ }
+
+ try {
+ if (output != null) {
+ output.write(c);
+ } else {
+ randomaccess.write(c);
+ }
+ } catch (java.io.IOException e) {
+ throw new java.lang.RuntimeException(
+ e.getMessage());
+ }
+ pushback = new java.util.Stack();
+ }
+
+ public void write(java.lang.String s) {
+ if (mode == INPUT) {
+ throw new java.lang.RuntimeException(
+ ""Attempted to write to input stream"");
+ }
+ for (int i = 0; i < s.length(); i++) {
+ if (s.charAt(i) == '\\n') {
+ line_number++;
+ }
+ }
+
+ try {
+ if (output != null) {
+ output.write(s.getBytes());
+ } else {
+ randomaccess.write(s.getBytes());
+ }
+ } catch (java.io.IOException e) {
+ throw new java.lang.RuntimeException(
+ e.getMessage());
+ }
+ pushback = new java.util.Stack();
+ }
+
+ public void flush() {
+ if (mode == INPUT) {
+ throw new java.lang.RuntimeException(
+ ""Attempted to flush input stream"");
+ }
+
+ try {
+ if (output != null) {
+ output.flush();
+ }
+ // else randomaccess already writes all data
+ // synchronously to the underlying device.
+ } catch (java.io.IOException e) {
+ throw new java.lang.RuntimeException(
+ e.getMessage());
+ }
+ }
+
+ public void close() {
+ try {
+ if (mode == INPUT) {
+ input.close();
+ } else if (mode == OUTPUT) {
+ output.close();
+ } else {
+ randomaccess.close();
+ }
+ } catch (java.io.IOException e) {
+ throw new java.lang.RuntimeException(
+ ""Error closing stream"");
+ }
+ }
+ }
+").
+
:- pragma foreign_code("C", "
MercuryFile mercury_stdin;
@@ -4704,6 +5148,28 @@
").
+:- pragma foreign_code("Java",
+"
+static MR_MercuryFileStruct mercury_stdin =
+ new MR_MercuryFileStruct(java.lang.System.in);
+static MR_MercuryFileStruct mercury_stdout =
+ new MR_MercuryFileStruct(java.lang.System.out);
+static MR_MercuryFileStruct mercury_stderr =
+ new MR_MercuryFileStruct(java.lang.System.err);
+static MR_MercuryFileStruct mercury_stdin_binary =
+ new MR_MercuryFileStruct(java.lang.System.in);
+static MR_MercuryFileStruct mercury_stdout_binary =
+ new MR_MercuryFileStruct(java.lang.System.out);
+
+static MR_MercuryFileStruct mercury_current_text_input = mercury_stdin;
+static MR_MercuryFileStruct mercury_current_text_output = mercury_stdout;
+static MR_MercuryFileStruct mercury_current_binary_input = mercury_stdin_binary;
+static MR_MercuryFileStruct mercury_current_binary_output =
+ mercury_stdout_binary;
+
+static java.lang.Exception MR_io_exception;
+").
+
:- pragma foreign_code("C", "
@@ -4783,6 +5249,29 @@
").
+:- pragma foreign_code("Java",
+"
+static MR_MercuryFileStruct mercury_open(String filename, String openmode) {
+ try {
+ if (openmode.charAt(0) == 'r') {
+ return new MR_MercuryFileStruct(filename);
+ }
+ if (openmode.charAt(0) == 'w') {
+ return new MR_MercuryFileStruct(filename);
+ }
+ if (openmode.charAt(0) == 'a') {
+ return new MR_MercuryFileStruct(filename, true);
+ }
+
+ throw new java.lang.RuntimeException(
+ ""Invalid file open mode: "" + openmode);
+ } catch (java.lang.Exception e) {
+ MR_io_exception = e;
+ }
+
+ return null;
+}
+").
:- pred throw_io_error(string::in) is erroneous.
:- pragma export(throw_io_error(in), "ML_throw_io_error").
@@ -4910,6 +5399,7 @@
").
+
:- pragma foreign_code("C", "
void
@@ -5387,6 +5877,35 @@
mf.putback = Byte;
}").
+:- pragma foreign_proc("Java",
+ io__read_char_code(File::in, CharCode::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure],
+"
+ CharCode = File.getc();
+").
+
+:- pragma foreign_proc("Java",
+ io__read_byte_val(File::in, ByteVal::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure],
+"
+ ByteVal = File.getc();
+").
+
+:- pragma foreign_proc("Java",
+ io__putback_char(File::in, Character::in, _IO0::di, _IO::uo),
+ [may_call_mercury, promise_pure],
+"
+ File.ungetc(Character);
+").
+
+:- pragma foreign_proc("Java",
+ io__putback_byte(File::in, Byte::in, _IO0::di, _IO::uo),
+ [may_call_mercury, promise_pure],
+"
+ File.ungetc(Byte);
+").
+
+
/* output predicates - with output to mercury_current_text_output */
:- pragma foreign_proc("C",
@@ -5569,6 +6088,34 @@
System.out.print(Val);
").
+:- pragma foreign_proc("Java",
+ io__write_byte(Byte::in, _IO0::di, _IO::uo),
+ [may_call_mercury, promise_pure, thread_safe, tabled_for_io],
+"
+ mercury_current_binary_output.putc(Byte);
+").
+
+:- pragma foreign_proc("Java",
+ io__write_bytes(Message::in, _IO0::di, _IO::uo),
+ [may_call_mercury, promise_pure, thread_safe, tabled_for_io],
+"{
+ mercury_current_binary_output.write(Message);
+}").
+
+:- pragma foreign_proc("Java",
+ io__flush_output(_IO0::di, _IO::uo),
+ [may_call_mercury, promise_pure, thread_safe, tabled_for_io],
+"
+ mercury_current_text_output.flush();
+").
+
+:- pragma foreign_proc("Java",
+ io__flush_binary_output(_IO0::di, _IO::uo),
+ [may_call_mercury, promise_pure, thread_safe, tabled_for_io],
+"
+ mercury_current_binary_output.flush();
+").
+
io__write_float(Float) -->
io__write_string(string__float_to_string(Float)).
@@ -5772,6 +6319,76 @@
Stream.stream.Flush();
}").
+:- pragma foreign_proc("Java",
+ io__seek_binary_2(Stream::in, Flag::in, Off::in, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io, thread_safe],
+"
+ Stream.seek(Flag, Off);
+").
+
+:- pragma foreign_proc("Java",
+ io__binary_stream_offset(Stream::in, Offset::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io, thread_safe],
+"
+ Offset = Stream.getOffset();
+").
+
+:- pragma foreign_proc("Java",
+ io__write_string(Stream::in, Message::in, _IO0::di, _IO::uo),
+ [may_call_mercury, promise_pure, thread_safe, tabled_for_io],
+"
+ Stream.write(Message);
+").
+
+:- pragma foreign_proc("Java",
+ io__write_char(Stream::in, Character::in, _IO0::di, _IO::uo),
+ [may_call_mercury, promise_pure, thread_safe, tabled_for_io],
+"
+ Stream.putc(Character);
+").
+
+:- pragma foreign_proc("Java",
+ io__write_int(Stream::in, Val::in, _IO0::di, _IO::uo),
+ [may_call_mercury, promise_pure, tabled_for_io, thread_safe],
+"
+ Stream.write(java.lang.String.valueOf(Val));
+").
+
+:- pragma foreign_proc("Java",
+ io__write_float(Stream::in, Val::in, _IO0::di, _IO::uo),
+ [may_call_mercury, promise_pure, tabled_for_io, thread_safe],
+"
+ Stream.write(java.lang.String.valueOf(Val));
+").
+
+:- pragma foreign_proc("Java",
+ io__write_byte(Stream::in, Byte::in, _IO0::di, _IO::uo),
+ [may_call_mercury, promise_pure, thread_safe, tabled_for_io],
+"
+ Stream.putc(Byte);
+").
+
+:- pragma foreign_proc("Java",
+ io__write_bytes(Stream::in, Message::in, _IO0::di, _IO::uo),
+ [may_call_mercury, promise_pure, thread_safe, tabled_for_io],
+"
+ Stream.write(Message);
+").
+
+:- pragma foreign_proc("Java",
+ io__flush_output(Stream::in, _IO0::di, _IO::uo),
+ [may_call_mercury, promise_pure, thread_safe, tabled_for_io],
+"
+ Stream.flush();
+").
+
+:- pragma foreign_proc("Java",
+ io__flush_binary_output(Stream::in, _IO0::di, _IO::uo),
+ [may_call_mercury, promise_pure, thread_safe, tabled_for_io],
+"
+ Stream.flush();
+").
+
io__write_float(Stream, Float) -->
io__write_string(Stream, string__float_to_string(Float)).
@@ -6119,6 +6736,162 @@
mercury_current_binary_output = NewStream;
").
+:- pragma foreign_proc("Java",
+ io__stdin_stream(Stream::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, thread_safe, tabled_for_io],
+"
+ Stream = mercury_stdin;
+").
+
+:- pragma foreign_proc("Java",
+ io__stdout_stream(Stream::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, thread_safe, tabled_for_io],
+"
+ Stream = mercury_stdout;
+").
+
+:- pragma foreign_proc("Java",
+ io__stderr_stream(Stream::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, thread_safe, tabled_for_io],
+"
+ Stream = mercury_stderr;
+").
+
+:- pragma foreign_proc("Java",
+ io__stdin_binary_stream(Stream::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, thread_safe, tabled_for_io],
+"
+ Stream = mercury_stdin_binary;
+").
+
+:- pragma foreign_proc("Java",
+ io__stdout_binary_stream(Stream::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, thread_safe, tabled_for_io],
+"
+ Stream = mercury_stdout_binary;
+").
+
+:- pragma foreign_proc("Java",
+ io__input_stream(Stream::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io],
+"
+ Stream = mercury_current_text_input;
+").
+
+:- pragma foreign_proc("Java",
+ io__output_stream(Stream::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io],
+"
+ Stream = mercury_current_text_output;
+").
+
+:- pragma foreign_proc("Java",
+ io__binary_input_stream(Stream::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io],
+"
+ Stream = mercury_current_binary_input;
+").
+
+:- pragma foreign_proc("Java",
+ io__binary_output_stream(Stream::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io],
+"
+ Stream = mercury_current_binary_output;
+").
+
+:- pragma foreign_proc("Java",
+ io__get_line_number(LineNum::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io],
+"
+ LineNum = mercury_current_text_input.line_number;
+").
+
+:- pragma foreign_proc("Java",
+ io__get_line_number(Stream::in, LineNum::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io],
+"{
+ LineNum = Stream.line_number;
+}").
+
+:- pragma foreign_proc("Java",
+ io__set_line_number(LineNum::in, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io],
+"
+ mercury_current_text_input.line_number = LineNum;
+").
+
+:- pragma foreign_proc("Java",
+ io__set_line_number(Stream::in, LineNum::in, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io],
+"{
+ Stream.line_number = LineNum;
+}").
+
+:- pragma foreign_proc("Java",
+ io__get_output_line_number(LineNum::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io],
+"
+ LineNum = mercury_current_text_output.line_number;
+").
+
+:- pragma foreign_proc("Java",
+ io__get_output_line_number(Stream::in, LineNum::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io],
+"{
+ LineNum = Stream.line_number;
+}").
+
+:- pragma foreign_proc("Java",
+ io__set_output_line_number(LineNum::in, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io],
+"
+ mercury_current_text_output.line_number = LineNum;
+").
+
+:- pragma foreign_proc("Java",
+ io__set_output_line_number(Stream::in, LineNum::in, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io],
+"{
+ Stream.line_number = LineNum;
+}").
+
+% io__set_input_stream(NewStream, OldStream, IO0, IO1)
+% Changes the current input stream to the stream specified.
+% Returns the previous stream.
+:- pragma foreign_proc("Java",
+ io__set_input_stream(NewStream::in, OutStream::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io],
+"
+ OutStream = mercury_current_text_input;
+ mercury_current_text_input = NewStream;
+").
+
+:- pragma foreign_proc("Java",
+ io__set_output_stream(NewStream::in, OutStream::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io],
+"
+ OutStream = mercury_current_text_output;
+ mercury_current_text_output = NewStream;
+").
+
+:- pragma foreign_proc("Java",
+ io__set_binary_input_stream(NewStream::in, OutStream::out,
+ _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io],
+"
+ OutStream = mercury_current_binary_input;
+ mercury_current_binary_input = NewStream;
+").
+
+:- pragma foreign_proc("Java",
+ io__set_binary_output_stream(NewStream::in, OutStream::out,
+ _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io],
+"
+ OutStream = mercury_current_binary_output;
+ mercury_current_binary_output = NewStream;
+").
+
/* stream open/close predicates */
% io__do_open_binary(File, Mode, ResultCode, StreamId, Stream, IO0, IO):
@@ -6191,6 +6964,38 @@
}
").
+:- pragma foreign_proc("Java",
+ io__do_open_text(FileName::in, Mode::in, ResultCode::out,
+ StreamId::out, Stream::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io, thread_safe],
+"
+ try {
+ Stream = mercury_open(FileName, Mode);
+ StreamId = Stream.id;
+ ResultCode = 0;
+ } catch (java.lang.Exception e) {
+ Stream = null;
+ StreamId = -1;
+ ResultCode = -1;
+ }
+").
+
+:- pragma foreign_proc("Java",
+ io__do_open_binary(FileName::in, Mode::in, ResultCode::out,
+ StreamId::out, Stream::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io, thread_safe],
+"
+ try {
+ Stream = mercury_open(FileName, Mode);
+ StreamId = Stream.id;
+ ResultCode = 0;
+ } catch (java.lang.Exception e) {
+ Stream = null;
+ StreamId = -1;
+ ResultCode = -1;
+ }
+").
+
io__close_input(Stream) -->
io__maybe_delete_stream_info(Stream),
io__close_stream(Stream).
@@ -6224,6 +7029,13 @@
mercury_close(Stream);
").
+:- pragma foreign_proc("Java",
+ io__close_stream(Stream::in, _IO0::di, _IO::uo),
+ [may_call_mercury, promise_pure, tabled_for_io, thread_safe],
+"
+ Stream.close();
+").
+
/* miscellaneous predicates */
:- pragma foreign_proc("C",
@@ -6426,6 +7238,76 @@
}
").
+:- pragma foreign_proc("Java",
+ io__progname(_Default::in, PrognameOut::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io, thread_safe],
+"
+ PrognameOut = ""java "" + mercury.runtime.JavaInternal.progname;
+").
+
+:- pragma foreign_proc("Java",
+ io__get_exit_status(ExitStatus::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io],
+"
+ ExitStatus = mercury.runtime.JavaInternal.exit_status;
+").
+
+:- pragma foreign_proc("Java",
+ io__set_exit_status(ExitStatus::in, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io],
+"
+ mercury.runtime.JavaInternal.exit_status = ExitStatus;
+").
+
+io__command_line_arguments(Args, IO, IO) :-
+ build_command_line_args(0, Args).
+
+:- pred build_command_line_args(int, list(string)).
+:- mode build_command_line_args(in, out) is det.
+
+build_command_line_args(ArgNumber, Args) :-
+ ( command_line_argument(ArgNumber, Arg) ->
+ Args = [Arg|MoreArgs],
+ build_command_line_args(ArgNumber + 1, MoreArgs)
+ ;
+ Args = []
+ ).
+
+:- pred command_line_argument(int, string).
+:- mode command_line_argument(in, out) is semidet.
+
+:- pragma foreign_proc("Java",
+ command_line_argument(ArgNum::in, Arg::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ String[] arg_vector = mercury.runtime.JavaInternal.args;
+
+ if (ArgNum < arg_vector.length && ArgNum >= 0) {
+ Arg = arg_vector[ArgNum];
+ succeeded = true;
+ } else {
+ Arg = null;
+ succeeded = false;
+ }
+").
+
+:- pragma foreign_proc("Java",
+ io__call_system_code(Command::in, Status::out, Msg::out,
+ _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io],
+"
+ try {
+ java.lang.Process command = java.lang.Runtime.getRuntime().
+ exec(Command);
+ command.waitFor();
+ Status = command.exitValue();
+ Msg = null;
+ } catch (java.lang.Exception e) {
+ Status = 127;
+ Msg = e.getMessage();
+ }
+").
+
/*---------------------------------------------------------------------------*/
/* io__getenv and io__setenv */
@@ -6452,6 +7334,29 @@
SUCCESS_INDICATOR = (Value != null);
}").
+:- pragma foreign_proc("Java",
+ io__getenv(Var::in, Value::out),
+ [will_not_call_mercury, tabled_for_io],
+"
+ // Note that this approach only works for environmental variables that
+ // are recognized by Java and hava a special format.
+ // (eg os.name, user.timezone etc)
+ // To add custom environmental variables, they must be set at the
+ // command line with java's -D option
+ // (ie java -DENV_VARIABLE_NAME=$ENV_VARIABLE_NAME ClassName)
+ // XXX Perhaps a better approach would be to determine the OS at
+ // runtime and then Runtime.exec() the equivalent of 'env'?
+
+ try {
+ Value = java.lang.System.getProperty(Var);
+ succeeded = (Value != null);
+ } catch (java.lang.Exception e) {
+ Value = null;
+ succeeded = false;
+ }
+").
+
+
io__setenv(Var, Value) :-
impure io__putenv(Var ++ "=" ++ Value).
@@ -6485,6 +7390,33 @@
SUCCESS_INDICATOR = (mercury.runtime.PInvoke._putenv(VarAndValue) == 0);
").
+:- pragma foreign_proc("Java",
+ io__setenv(Var::in, Value::in),
+ [will_not_call_mercury, tabled_for_io],
+"
+ // XXX see io__getenv/2
+
+ try {
+ Value = java.lang.System.setProperty(Var, Value);
+ succeeded = true;
+ } catch (java.lang.Exception e) {
+ succeeded = false;
+ }
+").
+
+:- pragma foreign_proc("Java",
+ io__putenv(VarAndValue::in),
+ [will_not_call_mercury, tabled_for_io],
+"
+ // This procedure should never be called, as io__setenv/2 has been
+ // implemented directly for Java.
+ // This implementation is included only to suppress warnings.
+
+ throw new RuntimeException(
+ ""io__putenv/1 not implemented for Java: "" +
+ VarAndValue);
+").
+
/*---------------------------------------------------------------------------*/
io__tmpnam(Name) -->
@@ -6663,6 +7595,48 @@
}
}").
+% For the Java implementation, io__make_temp/3 is overwritten directly, since
+% Java is capable of locating the default temp directory itself.
+
+:- pragma foreign_proc("Java",
+ io__do_make_temp(_Dir::in, _Prefix::in, _Sep::in, _FileName::out,
+ _Error::out, _ErrorMessage::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io, thread_safe],
+"
+ // this function should never be called.
+
+ throw new RuntimeException(""io__do_make_temp not implemented"");
+").
+
+:- pragma foreign_proc("Java",
+ io__make_temp(FileName::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io, thread_safe],
+"
+ try {
+ FileName = java.io.File.createTempFile(""mercury"", null).
+ getName();
+ } catch (java.lang.Exception e) {
+ throw new RuntimeException(e.getMessage());
+ }
+").
+
+:- pragma foreign_proc("Java",
+ io__make_temp(Dir::in, Prefix::in, FileName::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io, thread_safe],
+"
+ try {
+ if (Prefix.length() < 3) {
+ Prefix = Prefix + ""xxx"";
+ } else if (Prefix.length() > 5) {
+ Prefix = Prefix.substring(0, 5);
+ }
+ FileName = java.io.File.createTempFile(Prefix, null,
+ new java.io.File(Dir)).getName();
+ } catch (java.lang.Exception e) {
+ throw new RuntimeException(e.getMessage());
+ }
+").
+
/*---------------------------------------------------------------------------*/
:- pragma foreign_decl("C", "
@@ -6819,6 +7793,32 @@
}
}").
+:- pragma foreign_proc("Java",
+ io__remove_file_2(FileName::in, RetVal::out, RetStr::out,
+ _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io, thread_safe],
+"
+ try {
+ java.io.File file = new java.io.File(FileName);
+
+ if (file.exists()) {
+ if (file.delete()) {
+ RetVal = 0;
+ RetStr = """";
+ } else {
+ RetVal = -1;
+ RetStr = ""remove_file failed"";
+ }
+ } else {
+ RetVal = -1;
+ RetStr = ""remove failed: No such file or directory"";
+ }
+ } catch (java.lang.Exception e) {
+ RetVal = -1;
+ RetStr = e.getMessage();
+ }
+").
+
io__rename_file(OldFileName, NewFileName, Result, IO0, IO) :-
io__rename_file_2(OldFileName, NewFileName, Res, ResString, IO0, IO),
( Res \= 0 ->
@@ -6862,6 +7862,32 @@
}
}").
+:- pragma foreign_proc("Java",
+ io__rename_file_2(OldFileName::in, NewFileName::in, RetVal::out,
+ RetStr::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io, thread_safe],
+"
+ try {
+ java.io.File file = new java.io.File(OldFileName);
+
+ if (file.exists()) {
+ if (file.renameTo(new java.io.File(NewFileName))) {
+ RetVal = 0;
+ RetStr = """";
+ } else {
+ RetVal = -1;
+ RetStr = ""rename_file failed"";
+ }
+ } else {
+ RetVal = -1;
+ RetStr = ""rename failed: No such file or directory"";
+ }
+ } catch (java.lang.Exception e) {
+ RetVal = -1;
+ RetStr = e.getMessage();
+ }
+").
+
io__have_symlinks :- semidet_fail.
:- pragma foreign_proc("C", io__have_symlinks,
@@ -6972,6 +7998,30 @@
MR_update_io(IO0, IO);
}").
+% Since io__have_symlinks will fail for Java, these procedures should never be
+% called:
+
+:- pragma foreign_proc("Java",
+ io__make_symlink_2(_FileName::in, _LinkFileName::in,
+ _Status::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io, thread_safe],
+"
+ if (true) {
+ throw new java.lang.RuntimeException(
+ ""io__make_symlink_2 not implemented"");
+ }
+").
+
+:- pragma foreign_proc("Java",
+ io__read_symlink_2(_FileName::in, _TargetFileName::out,
+ _Status::out, _Error::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io, thread_safe],
+"
+ if (true) {
+ throw new java.lang.RuntimeException(
+ ""io__read_symlink_2 not implemented"");
+ }
+").
/*---------------------------------------------------------------------------*/
--------------------------------------------------------------------------
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