for review: io__rename_file

Fergus Henderson fjh at cs.mu.OZ.AU
Fri Feb 27 22:01:58 AEDT 1998


Tom,

Can you please review this one?

Estimated hours taken: 0.5

library/io.m:
	Add a new predicate `io__rename_file', which calls the ANSI C
	function rename().

	Also improve the documentation and error messages
	for `io__remove_file' (document that the behaviour is
	implementation-dependent if you attempt to remove an
	open file; prefix the error message with "remove failed: ").

Index: io.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/io.m,v
retrieving revision 1.149
diff -u -u -r1.149 io.m
--- io.m	1998/02/04 07:18:34	1.149
+++ io.m	1998/02/27 10:52:38
@@ -822,6 +822,8 @@
 
 %-----------------------------------------------------------------------------%
 
+% File handling predicates
+
 :- pred io__tmpnam(string, io__state, io__state).
 :- mode io__tmpnam(out, di, uo) is det.
 	% io__tmpnam(Name, IO0, IO) binds `Name' to a temporary
@@ -843,6 +845,20 @@
 	% io__remove_file(FileName, Result, IO0, IO) attempts to remove the
 	% file `FileName', binding Result to ok/0 if it succeeds, or
 	% error/1 if it fails.
+	% If `FileName' names a file that is currently open,
+	% the behaviour is implementation-dependent.
+
+:- pred io__rename_file(string, string, io__res, io__state, io__state).
+:- mode io__rename_file(in, in, out, di, uo) is det.
+	% io__rename_file(OldFileName, NewFileName, Result, IO0, IO)
+	% attempts to rename the file `OldFileName' as `NewFileName',
+	% binding Result to ok/0 if it succeeds, or error/1 if it fails.
+	% If `OldFileName' names a file that is currently open,
+	% the behaviour is implementation-dependent.
+	% If `NewFileName' names a file that already exists
+	% the behaviour is also implementation-dependent;
+	% on some systems, the file previously named `NewFileName' will be
+	% deleted and replaced with the file previously named `OldFileName'.
 
 %-----------------------------------------------------------------------------%
 
@@ -2720,38 +2736,78 @@
 
 /*---------------------------------------------------------------------------*/
 
+:- pragma c_header_code("
+
+#include <string.h>
+#include <errno.h>
+
+/*
+** ML_maybe_make_err_msg(was_error, msg, error_msg):
+**	if `was_error' is true, then append `msg' and `strerror(errno)'
+**	to give `error_msg'; otherwise, set `error_msg' to NULL.
+**
+** This is defined as a macro rather than a C function
+** to avoid worrying about the `hp' register being
+** invalidated by the function call.
+*/
+#define ML_maybe_make_err_msg(was_error, msg, error_msg)		\\
+	do {								\\
+		char *errno_msg;					\\
+		size_t len;						\\
+		Word tmp;						\\
+									\\
+		if (was_error) {					\\
+			errno_msg = strerror(errno);			\\
+			len = strlen(msg) + strlen(errno_msg);		\\
+			incr_hp_atomic(tmp,				\\
+				(len + sizeof(Word)) / sizeof(Word));	\\
+			(error_msg) = (char *)tmp;			\\
+			strcpy((error_msg), msg);			\\
+			strcat((error_msg), errno_msg);			\\
+		} else {						\\
+			(error_msg) = NULL;				\\
+		}							\\
+	} while(0)
+
+").
+
 io__remove_file(FileName, Result, IO0, IO) :-
 	io__remove_file_2(FileName, Res, ResString, IO0, IO),
-	( Res < 0 ->
+	( Res \= 0 ->
 		Result = error(ResString)
 	;
 		Result = ok
 	).
 
-
 :- pred io__remove_file_2(string, int, string, io__state, io__state).
 :- mode io__remove_file_2(in, out, out, di, uo) is det.
 
-%#include <string.h>
-%#include <errno.h>
-%#include "prof.h" % for strerror
-:- pragma(c_code, io__remove_file_2(FileName::in, RetVal::out, RetStr::out,
-		IO0::di, IO::uo), "{
-	Word tmp;
-	char *buf;
-
+:- pragma c_code(io__remove_file_2(FileName::in, RetVal::out, RetStr::out,
+		IO0::di, IO::uo), will_not_call_mercury,
+"{
 	RetVal = remove(FileName);
-
-	if (RetVal < 0) {
-		buf = strerror(errno);
-		incr_hp_atomic(tmp,(strlen(buf)+sizeof(Word)) / sizeof(Word));
-		RetStr = (char *)tmp;
-		strcpy(RetStr, buf);
-	} else {
-		RetStr = NULL;
-	}
+	ML_maybe_make_err_msg(RetVal != 0, ""remove failed: "", RetStr);
 	update_io(IO0, IO);
 }").
 
+io__rename_file(OldFileName, NewFileName, Result, IO0, IO) :-
+	io__rename_file_2(OldFileName, NewFileName, Res, ResString, IO0, IO),
+	( Res \= 0 ->
+		Result = error(ResString)
+	;
+		Result = ok
+	).
+
+:- pred io__rename_file_2(string, string, int, string, io__state, io__state).
+:- mode io__rename_file_2(in, in, out, out, di, uo) is det.
+
+:- pragma c_code(io__rename_file_2(OldFileName::in, NewFileName::in,
+		RetVal::out, RetStr::out, IO0::di, IO::uo),
+		will_not_call_mercury,
+"{
+	RetVal = rename(OldFileName, NewFileName);
+	ML_maybe_make_err_msg(RetVal != 0, ""rename failed: "", RetStr);
+	update_io(IO0, IO);
+}").
 
 /*---------------------------------------------------------------------------*/

-- 
Fergus Henderson <fjh at cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3         |     -- the last words of T. S. Garp.



More information about the developers mailing list