[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