[m-rev.] for review: fix io.file_id with lcc

Simon Taylor stayl at cs.mu.OZ.AU
Fri Jul 25 02:00:27 AEST 2003


Estimated hours taken: 2
Branches: main

Make io.file_id compile with lcc on Linux.

configure.in:
mercury_conf.h.in:
	Test for dev_t and ino_t.

	Require Autoconf 2.50.
	Autoconf 2.13 doesn't have AC_CHECK_TYPES, and
	AC_CHECK_TYPE is broken.

INSTALL_CVS:
	Document the required version of autoconf.

library/io.m:
	Handle systems which don't define dev_t or ino_t.

	Handle systems which implement dev_t or ino_t as
	a struct (e.g. glibc with lcc).

Index: INSTALL_CVS
===================================================================
RCS file: /home/mercury1/repository/mercury/INSTALL_CVS,v
retrieving revision 1.7
diff -u -u -r1.7 INSTALL_CVS
--- INSTALL_CVS	5 Mar 2003 03:52:53 -0000	1.7
+++ INSTALL_CVS	24 Jul 2003 14:15:53 -0000
@@ -2,11 +2,12 @@
 #
 # INSTALL_CVS - installation instructions and installation script.
 #	This version is for use by Mercury developers after you have
-#       just checked the files out from the CVS archive. 
-#        Note: you need a previous version of Mercury
-#	already installed (the CVS archive doesn't have all the necessary
-#	files for bootstrapping).
-#	You also need autoconf (and hence GNU m4) installed.
+#	just checked the files out from the CVS archive. 
+#	Note: you need a previous version of Mercury already installed
+#	(the CVS archive doesn't have all the necessary files for
+#	bootstrapping).
+#	You also need autoconf (version 2.50 or later) (and hence GNU m4)
+#	installed.
 #
 # Step 0.  autoconf
 #
Index: configure.in
===================================================================
RCS file: /home/mercury1/repository/mercury/configure.in,v
retrieving revision 1.370
diff -u -u -r1.370 configure.in
--- configure.in	21 Jul 2003 14:08:32 -0000	1.370
+++ configure.in	24 Jul 2003 14:10:04 -0000
@@ -19,6 +19,10 @@
 #-----------------------------------------------------------------------------#
 AC_INIT(scripts/mmc.in)
 TMPDIR=${TMPDIR=/tmp}
+
+# AC_CHECK_TYPES does not exist in versions of autoconf before 2.50.
+# AC_CHECK_TYPE is broken in versions of autoconf before 2.50.
+AC_PREREQ(2.50)
 #-----------------------------------------------------------------------------#
 #
 # Ensure that all messages are saved to a file `configure.log' by
@@ -1254,6 +1258,15 @@
 AC_SUBST(MR_UINT_LEAST32_MAX)
 #-----------------------------------------------------------------------------#
 AC_TYPE_PID_T
+
+AC_CHECK_TYPES([dev_t, ino_t])
+case "$ac_cv_type_dev_t" in
+	yes) AC_DEFINE_UNQUOTED(MR_HAVE_DEV_T) ;;
+esac
+case "$ac_cv_type_ino_t" in
+	yes) AC_DEFINE_UNQUOTED(MR_HAVE_INO_T) ;;
+esac
+
 #-----------------------------------------------------------------------------#
 AC_MSG_CHECKING(for an integer type of at least 16 bits)
 AC_CACHE_VAL(mercury_cv_int_least16_type,
Index: library/io.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/io.m,v
retrieving revision 1.300
diff -u -u -r1.300 io.m
--- library/io.m	24 Jul 2003 03:02:29 -0000	1.300
+++ library/io.m	24 Jul 2003 13:00:09 -0000
@@ -2829,14 +2829,79 @@
 
 %-----------------------------------------------------------------------------%
 
-:- type file_id
-	---> file_id(device :: int, inode :: int).
+:- type file_id ---> file_id.
+:- pragma foreign_type("C", file_id, "ML_File_Id") where
+		comparison is compare_file_id.
+
+:- pragma foreign_decl("C",
+"
+#ifdef MR_HAVE_DEV_T
+  typedef	dev_t		ML_dev_t;
+#else
+  typedef	MR_Integer	ML_dev_t;
+#endif
+
+#ifdef MR_HAVE_INO_T
+  typedef	ino_t		ML_ino_t;
+#else
+  typedef	MR_Integer	ML_ino_t;
+#endif
+
+typedef struct {
+  	ML_dev_t device;
+  	ML_ino_t inode;
+} ML_File_Id;
+").
+
+:- pred compare_file_id(comparison_result::uo,
+		file_id::in, file_id::in) is det.
+
+compare_file_id(Result, FileId1, FileId2) :-
+	compare_file_id_2(Result0, FileId1, FileId2),
+	Result =
+	    ( if Result0 < 0 then (<) else if Result0 = 0 then (=) else (>) ).
+
+:- pred compare_file_id_2(int::out, file_id::in, file_id::in) is det.
+
+:- pragma foreign_proc("C",
+	compare_file_id_2(Res::out, FileId1::in, FileId2::in),
+	[will_not_call_mercury, promise_pure, thread_safe],
+"
+	int device_cmp;
+	int inode_cmp;
+
+	/*
+	** For compilers other than GCC, glibc defines dev_t as
+	** struct (dev_t is 64 bits, and other compilers may
+	** not have a 64 bit arithmetic type).
+	** XXX This code assumes that dev_t and ino_t do not include
+	** padding bits.  In practice, that should be OK.
+	*/
+	device_cmp = memcmp(&(FileId1.device), &(FileId2.device),
+			sizeof(ML_dev_t));
+
+	if (device_cmp < 0) {
+		Res = -1;
+	} else if (device_cmp > 0) {
+		Res = 1;
+	} else {
+		inode_cmp = memcmp(&(FileId1.inode), &(FileId2.inode),
+				sizeof(ML_ino_t));
+		if (device_cmp < 0) {
+			Res = -1;
+		} else if (device_cmp > 0) {
+			Res = 1;
+		} else {	
+			Res = 0;
+		}
+	}
+").
 
 io__file_id(FileName, Result) -->
 	( { have_file_ids } ->
-		io__file_id_2(FileName, Status, Msg, Device, Inode),
+		io__file_id_2(FileName, Status, Msg, FileId),
 		( { Status = 1 } ->
-			{ Result = ok(file_id(Device, Inode)) }
+			{ Result = ok(FileId) }
 		;
 			{ Result = error(io_error(Msg)) }
 		)
@@ -2845,20 +2910,19 @@
 	make_io_error("io.file_id not implemented on this platform")) }
 	).
 
-:- pred io__file_id_2(string, int, string, int, int,
-		io__state, io__state).
-:- mode io__file_id_2(in, out, out, out, out, di, uo) is det.
+:- pred io__file_id_2(string, int, string, file_id, io__state, io__state).
+:- mode io__file_id_2(in, out, out, out, di, uo) is det.
 
 :- pragma foreign_proc("C",
 	io__file_id_2(FileName::in, Status::out, Msg::out,
-		Device::out, Inode::out, IO0::di, IO::uo),
+		FileId::out, IO0::di, IO::uo),
 	[will_not_call_mercury, promise_pure, tabled_for_io, thread_safe],
 "{
 #ifdef MR_HAVE_STAT
 	struct stat s;
 	if (stat(FileName, &s) == 0) {
-		Device = s.st_dev;
-		Inode = s.st_ino;
+		FileId.device = s.st_dev;
+		FileId.inode = s.st_ino;
 		Msg = MR_string_const("""", 0);
 		Status = 1;
 	} else {
Index: runtime/mercury_conf.h.in
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_conf.h.in,v
retrieving revision 1.49
diff -u -u -r1.49 mercury_conf.h.in
--- runtime/mercury_conf.h.in	21 Jul 2003 14:08:41 -0000	1.49
+++ runtime/mercury_conf.h.in	24 Jul 2003 13:00:09 -0000
@@ -162,9 +162,13 @@
 **
 **	MR_HAVE_INTPTR_T	we have intptr_t and uintptr_t
 **	MR_HAVE_INT_LEASTN_T	we have {u,}int_least{8,16,32}_t
+**	MR_HAVE_DEV_T		we have dev_t
+**	MR_HAVE_INO_T		we have ino_t
 */
 #undef MR_HAVE_INTPTR_T
 #undef MR_HAVE_INT_LEASTN_T
+#undef MR_HAVE_DEV_T
+#undef MR_HAVE_INO_T
 
 /*
 ** pid_t is defined as `int' iff the system headers don't define it.
--------------------------------------------------------------------------
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