[m-rev.] for review: add dir.current_directory

Peter Wang novalazy at gmail.com
Wed Sep 19 17:02:54 AEST 2007


Estimated hours taken: 1.5
Branches: main

NEWS:
library/dir.m:
	Add a predicate to return the current working directory, currently
	implemented for C and Erlang backends.

library/io.m:
	Add supporting functions to create io.res(string) values from foreign
	code.

tests/hard_coded/dir_test.exp:
tests/hard_coded/dir_test.exp2:
tests/hard_coded/dir_test.m:
	Test the new predicate.


Index: NEWS
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/NEWS,v
retrieving revision 1.477
diff -u -r1.477 NEWS
--- NEWS	7 Sep 2007 15:08:16 -0000	1.477
+++ NEWS	19 Sep 2007 06:57:30 -0000
@@ -195,6 +195,8 @@
 * We have added a predicate io.remove_file_recursively/4
   which can remove non-empty directories.
 
+* We have added the predicate `dir.current_directory'.
+
 Changes to the Mercury compiler:
 
 * Support for the reserve tag grades has been removed.
Index: library/dir.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/library/dir.m,v
retrieving revision 1.42
diff -u -r1.42 dir.m
--- library/dir.m	17 Aug 2007 02:08:38 -0000	1.42
+++ library/dir.m	19 Sep 2007 06:57:30 -0000
@@ -164,6 +164,13 @@
 
 %-----------------------------------------------------------------------------%
 
+    % io.current_directory(Result)
+    % Return the current working directory.
+    %
+:- pred dir.current_directory(io.res(string)::out, io::di, io::uo) is det.
+
+%-----------------------------------------------------------------------------%
+
     % Make the given directory, and all parent directories.
     % This will also succeed if the directory already exists
     % and is readable and writable by the current user.
@@ -820,6 +827,50 @@
 
 %-----------------------------------------------------------------------------%
 
+:- pragma foreign_proc("C",
+    dir.current_directory(Res::out, IO0::di, IO::uo),
+    [may_call_mercury, promise_pure, tabled_for_io, terminates],
+"   
+    size_t      size = 256; 
+    char        *buf;
+    MR_String   str;
+
+    while (1) {
+        buf = MR_GC_NEW_ARRAY(char, size);
+        if (getcwd(buf, size)) {
+            MR_make_aligned_string(str, buf);
+            Res = ML_make_io_res_1_ok_string(str);
+            break;
+        }
+        if (errno != ERANGE) {
+            ML_make_io_res_1_error_string(errno,
+                MR_make_string_const(""dir.current_directory failed: ""),
+                &Res);
+            break;
+        }
+        /* Buffer too small.  Resize and try again. */
+        size *= 1.5;
+    }
+
+    IO = IO0;
+").
+
+:- pragma foreign_proc("Erlang",
+    dir.current_directory(Res::out, _IO0::di, _IO::uo),
+    [may_call_mercury, promise_pure, tabled_for_io, terminates],
+"
+    case file:get_cwd() of
+        {ok, Cwd} ->
+            Res = mercury__io:'ML_make_io_res_1_ok_string'(
+                list_to_binary(Cwd));
+        {error, Reason} ->
+            Res = mercury__io:'ML_make_io_res_1_error_string'(Reason,
+                ""dir.current_directory failed: "")
+    end
+").
+
+%-----------------------------------------------------------------------------%
+
 dir.make_directory(PathName, Result, !IO) :-
     ( can_implement_make_directory ->
         DirName = dir.dirname(PathName),
Index: library/io.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/library/io.m,v
retrieving revision 1.402
diff -u -r1.402 io.m
--- library/io.m	17 Aug 2007 02:08:39 -0000	1.402
+++ library/io.m	19 Sep 2007 06:57:31 -0000
@@ -3568,6 +3568,26 @@
 make_io_res_1_error_file_type(Error, Msg0, error(make_io_error(Msg)), !IO) :-
     io.make_err_msg(Error, Msg0, Msg, !IO).
 
+:- func make_io_res_1_ok_string(string) = io.res(string).
+:- pragma foreign_export("C", (make_io_res_1_ok_string(in) = out),
+    "ML_make_io_res_1_ok_string").
+:- pragma foreign_export("Erlang", (make_io_res_1_ok_string(in) = out),
+    "ML_make_io_res_1_ok_string").
+
+make_io_res_1_ok_string(String) = ok(String).
+
+:- pred make_io_res_1_error_string(io.system_error::in,
+    string::in, io.res(string)::out, io::di, io::uo) is det.
+:- pragma foreign_export("C",
+    make_io_res_1_error_string(in, in, out, di, uo),
+    "ML_make_io_res_1_error_string").
+:- pragma foreign_export("Erlang",
+    make_io_res_1_error_string(in, in, out, di, uo),
+    "ML_make_io_res_1_error_string").
+
+make_io_res_1_error_string(Error, Msg0, error(make_io_error(Msg)), !IO) :-
+    io.make_err_msg(Error, Msg0, Msg, !IO).
+
 %-----------------------------------------------------------------------------%
 
 :- type file_id ---> file_id.
Index: tests/hard_coded/dir_test.exp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/hard_coded/dir_test.exp,v
retrieving revision 1.2
diff -u -r1.2 dir_test.exp
--- tests/hard_coded/dir_test.exp	28 Jul 2003 15:50:45 -0000	1.2
+++ tests/hard_coded/dir_test.exp	19 Sep 2007 06:57:31 -0000
@@ -131,6 +131,7 @@
 "foo/"/"bar/baz" = "foo\bar\baz".
 checking whether `unwritable' is readable...ok
 unwritable file found to be unwritable
+current_directory succeeded: hard_coded
 make_directory succeeded
 make_directory succeeded
 dir.make_single_directory with non-existent parent failed as expected.
Index: tests/hard_coded/dir_test.exp2
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/hard_coded/dir_test.exp2,v
retrieving revision 1.2
diff -u -r1.2 dir_test.exp2
--- tests/hard_coded/dir_test.exp2	28 Jul 2003 15:50:45 -0000	1.2
+++ tests/hard_coded/dir_test.exp2	19 Sep 2007 06:57:31 -0000
@@ -128,6 +128,7 @@
 "foo/"/"bar/baz" = "foo/bar/baz".
 checking whether `unwritable' is readable...ok
 unwritable file found to be unwritable
+current_directory succeeded: hard_coded
 make_directory succeeded
 make_directory succeeded
 dir.make_single_directory with non-existent parent failed as expected.
Index: tests/hard_coded/dir_test.m
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/hard_coded/dir_test.m,v
retrieving revision 1.4
diff -u -r1.4 dir_test.m
--- tests/hard_coded/dir_test.m	29 Mar 2006 08:08:00 -0000	1.4
+++ tests/hard_coded/dir_test.m	19 Sep 2007 06:57:31 -0000
@@ -60,6 +60,19 @@
 		"unwritable file found to be unwritable\n")
 	),
 
+	dir__current_directory(CwdResult),
+	(
+	    { CwdResult = ok(Cwd) },
+	    io__write_string("current_directory succeeded: "),
+	    io__write_string(dir__det_basename(Cwd)),
+	    io__nl
+	;
+	    { CwdResult = error(Error) },
+	    io__write_string("current_directory failed: "),
+	    io__write_string(io__error_message(Error)),
+	    io__nl
+	),
+
 	{ Dir1 = "test_dir"/"d1" },
 	test0("make_directory", dir__make_directory(Dir1)),
 	% Test making a directory that already exists.

--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to:       mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions:          mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the reviews mailing list