[m-dev.] for review: string__fmt

Peter Ross peter.ross at miscrit.be
Thu Aug 17 02:35:58 AEST 2000


Fergus could you please review this diff.  It should fix the failure of
tests/general/string_format_test on the alpha.

===================================================================


Estimated hours taken: 1

Avoid the cast to long before printing integers.  This cast is
problematic when printing negative integers with the format string "%x".
For instance on the alpha a long is 64 bits and a MR_integer is 32 bits,
so printing -31 is printed as ffffffffffffffe1 instead of ffffffe1.

configure.in:
    Determine the length modifier to use for MR_Integer.

runtime/mercury_conf.h.in:
    Record the length modifer using the #define
    MR_INTEGER_LENGTH_MODIFIER.

library/string.m:
    Add a new function int_length_modifier which returns the length
    modifier to use for a MR_Integer.
    Add an extra argument to make_format which is the length modifier to
    use when constructing the format string.

Index: configure.in
===================================================================
RCS file: /home/mercury1/repository/mercury/configure.in,v
retrieving revision 1.217
diff -u -r1.217 configure.in
--- configure.in	2000/08/11 16:50:09	1.217
+++ configure.in	2000/08/16 16:18:53
@@ -836,6 +836,21 @@
 AC_DEFINE_UNQUOTED(MR_WORD_TYPE, $mercury_cv_word_type)
 MR_WORD_TYPE=$mercury_cv_word_type
 AC_SUBST(MR_WORD_TYPE)
+
+AC_DEFINE_UNQUOTED(MR_INT_LEAST16_TYPE, $mercury_cv_int_least16_type)
+MR_INT_LEAST16_TYPE=$mercury_cv_int_least16_type
+
+if test "$mercury_cv_word_type" = int; then
+	AC_DEFINE_UNQUOTED(MR_INTEGER_LENGTH_MODIFIER, "")
+elif test "$mercury_cv_word_type" = long; then
+	AC_DEFINE_UNQUOTED(MR_INTEGER_LENGTH_MODIFIER, "l")
+elif test "$mercury_cv_word_type" = "long long"; then
+	AC_DEFINE_UNQUOTED(MR_INTEGER_LENGTH_MODIFIER, "ll")
+else
+	AC_MSG_ERROR("Cannot determine the length modifier for the MR_Integer type.")
+fi
+AC_SUBST(MR_INTEGER_LENGTH_MODIFIER)
+
 #-----------------------------------------------------------------------------#
 AC_MSG_CHECKING(for an integer type of at least 64 bits)
 AC_CACHE_VAL(mercury_cv_int_least64_type,
Index: library/string.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/string.m,v
retrieving revision 1.126
diff -u -r1.126 string.m
--- library/string.m	2000/08/10 16:34:16	1.126
+++ library/string.m	2000/08/16 16:19:01
@@ -1150,66 +1150,73 @@
 			% valid int conversion specifiers
 		Spec = d(Int),
 		String = format_int(
-				make_format(Flags, Width, Prec, "ld"), Int)
+				make_format(Flags, Width,
+					Prec, int_length_modifier, "d"), Int)
 	;
 		Spec = i(Int),
 		String = format_int(
-				make_format(Flags, Width, Prec, "li"), Int)
+				make_format(Flags, Width,
+					Prec, int_length_modifier, "i"), Int)
 	;
 		Spec = o(Int),
 		String = format_int(
-				make_format(Flags, Width, Prec, "lo"), Int)
+				make_format(Flags, Width,
+					Prec, int_length_modifier, "o"), Int)
 	;
 		Spec = u(Int),
 		String = format_int(
-				make_format(Flags, Width, Prec, "lu"), Int)
+				make_format(Flags, Width,
+					Prec, int_length_modifier, "u"), Int)
 	;
 		Spec = x(Int),
 		String = format_int(
-				make_format(Flags, Width, Prec, "lx"), Int)
+				make_format(Flags, Width,
+					Prec, int_length_modifier, "x"), Int)
 	;
 		Spec = cX(Int),
 		String = format_int(
-				make_format(Flags, Width, Prec, "lX"), Int)
+				make_format(Flags, Width,
+					Prec, int_length_modifier, "X"), Int)
 	;
 		Spec = p(Int),
 		String = format_int(
-				make_format(Flags, Width, Prec, "lp"), Int)
+				make_format(Flags, Width,
+					Prec, int_length_modifier, "p"), Int)
 	;
 			% valid float conversion specifiers
 		Spec = e(Float),
 		String = format_float(
-				make_format(Flags, Width, Prec, "Le"), Float)
+			make_format(Flags, Width, Prec, "L", "e"), Float)
 	;
 		Spec = cE(Float),
 		String = format_float(
-				make_format(Flags, Width, Prec, "LE"), Float)
+			make_format(Flags, Width, Prec, "L", "E"), Float)
 	;
 		Spec = f(Float),
 		String = format_float(
-				make_format(Flags, Width, Prec, "Lf"), Float)
+			make_format(Flags, Width, Prec, "L", "f"), Float)
 	;
 		Spec = cF(Float),
 		String = format_float(
-				make_format(Flags, Width, Prec, "LF"), Float)
+			make_format(Flags, Width, Prec, "L", "F"), Float)
 	;
 		Spec = g(Float),
 		String = format_float(
-				make_format(Flags, Width, Prec, "Lg"), Float)
+			make_format(Flags, Width, Prec, "L", "g"), Float)
 	;
 		Spec = cG(Float),
 		String = format_float(
-				make_format(Flags, Width, Prec, "LG"), Float)
+			make_format(Flags, Width, Prec, "L", "G"), Float)
 	;
 			% valid char conversion Specifiers
 		Spec = c(Char),
 		String = format_char(
-				make_format(Flags, Width, Prec, "c"), Char)
+				make_format(Flags, Width, Prec, "", "c"), Char)
 	;
 			% valid string conversion Spec = ifiers
 		Spec = s(Str),
 		String = format_string(
-				make_format(Flags, Width, Prec, "s"), Str)
+				make_format(Flags, Width, Prec, "", "s"), Str)
 	;
 			% conversion specifier representing the "%" sign
 		Spec = percent,
@@ -1219,9 +1226,9 @@
 
 	% Construct a format string suitable to passing to sprintf.
 :- func make_format(list(char), maybe(list(char)),
-		maybe(list(char)), string) = string.
+		maybe(list(char)), string, string) = string.
 
-make_format(Flags, MaybeWidth, MaybePrec, Spec) = String :-
+make_format(Flags, MaybeWidth, MaybePrec, LengthMod, Spec) = String :-
 	(
 		MaybeWidth = yes(Width)
 	;
@@ -1237,8 +1244,16 @@
 	),
 	String = string__append_list(["%", from_char_list(Flags),
 				from_char_list(Width),
-				from_char_list(Prec), Spec]).
+				from_char_list(Prec), LengthMod, Spec]).
 
+:- func int_length_modifier = string.
+:- pragma c_code(int_length_modifier = (LengthModifier::out),
+		[will_not_call_mercury, thread_safe], "{
+	MR_make_aligned_string_copy(LengthModifier,
+			MR_INTEGER_LENGTH_MODIFIER);
+}").
+
+
 	% Create a string from a float using the format string.
 	% Note is is the responsibility of the caller to ensure that the
 	% format string is valid.
@@ -1254,13 +1269,7 @@
 :- func format_int(string, int) = string.
 :- pragma c_code(format_int(FormatStr::in, Val::in) = (Str::out),
 		[will_not_call_mercury, thread_safe], "{
-		/*
-		** XXX this cast to long may not be sufficient.
-		** For example on Win64 MR_Integer may be 64 bits and long
-		** only 32 bits.  However not all systems support long
-		** long, so this will have to do for the moment.
-		*/
-	Str = MR_make_string(MR_PROC_LABEL, FormatStr, (long) Val);
+	Str = MR_make_string(MR_PROC_LABEL, FormatStr, Val);
 }").
 
 	% Create a string from a string using the format string.
Index: runtime/mercury_conf.h.in
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_conf.h.in,v
retrieving revision 1.31
diff -u -r1.31 mercury_conf.h.in
--- runtime/mercury_conf.h.in	2000/08/11 16:50:19	1.31
+++ runtime/mercury_conf.h.in	2000/08/16 16:19:01
@@ -45,6 +45,11 @@
 */
 #undef	MR_WORD_TYPE
 
+/* 
+** MR_INTEGER_LENGTH_MODIFIER: the length modifier for an MR_Integer.
+*/
+#undef MR_INTEGER_LENGTH_MODIFIER
+
 /*
 ** MR_INT_LEAST64_TYPE:
 ** This must be a C integral type (e.g. int, long, long long)
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to:       mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions:          mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------



More information about the developers mailing list