diff --git a/tests/hard_coded/Mmakefile b/tests/hard_coded/Mmakefile index cfadcbbb2..dacc6d148 100644 --- a/tests/hard_coded/Mmakefile +++ b/tests/hard_coded/Mmakefile @@ -776,7 +776,6 @@ ifeq "$(findstring profdeep,$(GRADE))" "" array_shrink \ array_swap \ base_string_to_int \ - base_string_to_uint \ bit_access_uint16 \ bit_access_uint32 \ bit_access_uint64 \ diff --git a/tests/hard_coded/base_string_to_int.exp b/tests/hard_coded/base_string_to_int.exp index a1395cc88..3bdf441a3 100644 --- a/tests/hard_coded/base_string_to_int.exp +++ b/tests/hard_coded/base_string_to_int.exp @@ -1,178 +1,188 @@ -### Empty, blank and sign-only strings ### - -base_string_to_int(10, "") ==> no -base_string_to_int(2, "") ==> no -base_string_to_int(36, "") ==> no -base_string_to_int(10, " ") ==> no -base_string_to_int(2, " ") ==> no -base_string_to_int(36, " ") ==> no -base_string_to_int(10, "-") ==> no -base_string_to_int(10, "+") ==> no -base_string_to_int(16, "-") ==> no -base_string_to_int(2, "+") ==> no -base_string_to_int(10, "--") ==> no -base_string_to_int(10, "++") ==> no -base_string_to_int(10, "+-1") ==> no -base_string_to_int(10, "-+1") ==> no -base_string_to_int(10, " ") ==> no -base_string_to_int(10, "\t") ==> no -base_string_to_int(10, "\n") ==> no -base_string_to_int(10, " \t ") ==> no -base_string_to_int(10, "- ") ==> no -base_string_to_int(10, "+ ") ==> no +### Empty strings ### + +base_string_to_{int,uint}( 10, "") ==> no +base_string_to_{int,uint}( 2, "") ==> no +base_string_to_{int,uint}( 36, "") ==> no + +### Blank strings ### + +base_string_to_{int,uint}( 10, " ") ==> no +base_string_to_{int,uint}( 10, " ") ==> no +base_string_to_{int,uint}( 10, "\t") ==> no +base_string_to_{int,uint}( 10, "\n") ==> no +base_string_to_{int,uint}( 10, " \t ") ==> no +base_string_to_{int,uint}( 2, " ") ==> no +base_string_to_{int,uint}( 36, " ") ==> no + +### Signs ### + +base_string_to_{int,uint}( 10, "-1") ==> int = -1, uint = no +base_string_to_{int,uint}( 10, "+1") ==> int = 1, uint = no +base_string_to_{int,uint}( 10, "-0") ==> int = 0, uint = no +base_string_to_{int,uint}( 10, "+0") ==> int = 0, uint = no +base_string_to_{int,uint}( 10, "-") ==> no +base_string_to_{int,uint}( 10, "+") ==> no +base_string_to_{int,uint}( 16, "-") ==> no +base_string_to_{int,uint}( 2, "+") ==> no +base_string_to_{int,uint}( 10, "--") ==> no +base_string_to_{int,uint}( 10, "++") ==> no +base_string_to_{int,uint}( 10, "+-1") ==> no +base_string_to_{int,uint}( 10, "-+1") ==> no +base_string_to_{int,uint}( 10, "- ") ==> no +base_string_to_{int,uint}( 10, "+ ") ==> no ### Single digits ### -base_string_to_int(10, "0") ==> 0 -base_string_to_int(10, "7") ==> 7 -base_string_to_int(10, "-7") ==> -7 -base_string_to_int(10, "+7") ==> 7 -base_string_to_int(2, "0") ==> 0 -base_string_to_int(2, "1") ==> 1 -base_string_to_int(8, "7") ==> 7 -base_string_to_int(16, "f") ==> 15 -base_string_to_int(16, "F") ==> 15 -base_string_to_int(36, "z") ==> 35 -base_string_to_int(36, "Z") ==> 35 +base_string_to_{int,uint}( 10, "0") ==> 0 +base_string_to_{int,uint}( 10, "7") ==> 7 +base_string_to_{int,uint}( 10, "-7") ==> int = -7, uint = no +base_string_to_{int,uint}( 10, "+7") ==> int = 7, uint = no +base_string_to_{int,uint}( 2, "0") ==> 0 +base_string_to_{int,uint}( 2, "1") ==> 1 +base_string_to_{int,uint}( 8, "7") ==> 7 +base_string_to_{int,uint}( 16, "f") ==> 15 +base_string_to_{int,uint}( 16, "F") ==> 15 +base_string_to_{int,uint}( 36, "z") ==> 35 +base_string_to_{int,uint}( 36, "Z") ==> 35 ### Upper and lower case digits ### -base_string_to_int(16, "abcdef") ==> 11259375 -base_string_to_int(16, "ABCDEF") ==> 11259375 -base_string_to_int(16, "AbCdEf") ==> 11259375 -base_string_to_int(16, "-Ff") ==> -255 -base_string_to_int(36, "abz") ==> 13391 -base_string_to_int(36, "ABZ") ==> 13391 -base_string_to_int(36, "AbZ") ==> 13391 +base_string_to_{int,uint}( 16, "abcdef") ==> 11259375 +base_string_to_{int,uint}( 16, "ABCDEF") ==> 11259375 +base_string_to_{int,uint}( 16, "AbCdEf") ==> 11259375 +base_string_to_{int,uint}( 16, "-Ff") ==> int = -255, uint = no +base_string_to_{int,uint}( 36, "abz") ==> 13391 +base_string_to_{int,uint}( 36, "ABZ") ==> 13391 +base_string_to_{int,uint}( 36, "AbZ") ==> 13391 ### Leading zeros ### -base_string_to_int(10, "00") ==> 0 -base_string_to_int(10, "007") ==> 7 -base_string_to_int(10, "-007") ==> -7 -base_string_to_int(10, "+007") ==> 7 -base_string_to_int(2, "000101") ==> 5 -base_string_to_int(8, "00017") ==> 15 -base_string_to_int(16, "000ff") ==> 255 -base_string_to_int(36, "000z") ==> 35 -base_string_to_int(10, "0000000000000000000000000000000") ==> 0 -base_string_to_int(10, "0000000000000000000000000000001") ==> 1 +base_string_to_{int,uint}( 10, "00") ==> 0 +base_string_to_{int,uint}( 10, "007") ==> 7 +base_string_to_{int,uint}( 10, "-007") ==> int = -7, uint = no +base_string_to_{int,uint}( 10, "+007") ==> int = 7, uint = no +base_string_to_{int,uint}( 2, "000101") ==> 5 +base_string_to_{int,uint}( 8, "00017") ==> 15 +base_string_to_{int,uint}( 16, "000ff") ==> 255 +base_string_to_{int,uint}( 36, "000z") ==> 35 +base_string_to_{int,uint}( 10, "0000000000000000000000000000000") ==> 0 +base_string_to_{int,uint}( 10, "0000000000000000000000000000001") ==> 1 ### Digits not valid in the specified base ### -base_string_to_int(2, "1") ==> 1 -base_string_to_int(2, "2") ==> no -base_string_to_int(3, "2") ==> 2 -base_string_to_int(3, "3") ==> no -base_string_to_int(8, "7") ==> 7 -base_string_to_int(8, "8") ==> no -base_string_to_int(9, "8") ==> 8 -base_string_to_int(9, "9") ==> no -base_string_to_int(10, "9") ==> 9 -base_string_to_int(10, "a") ==> no -base_string_to_int(10, "A") ==> no -base_string_to_int(11, "a") ==> 10 -base_string_to_int(11, "A") ==> 10 -base_string_to_int(11, "b") ==> no -base_string_to_int(11, "B") ==> no -base_string_to_int(16, "f") ==> 15 -base_string_to_int(16, "g") ==> no -base_string_to_int(16, "G") ==> no -base_string_to_int(17, "g") ==> 16 -base_string_to_int(17, "h") ==> no -base_string_to_int(35, "y") ==> 34 -base_string_to_int(35, "z") ==> no -base_string_to_int(35, "Z") ==> no -base_string_to_int(36, "z") ==> 35 -base_string_to_int(36, "Z") ==> 35 -base_string_to_int(2, "102") ==> no -base_string_to_int(8, "178") ==> no -base_string_to_int(16, "1fg") ==> no +base_string_to_{int,uint}( 2, "1") ==> 1 +base_string_to_{int,uint}( 2, "2") ==> no +base_string_to_{int,uint}( 3, "2") ==> 2 +base_string_to_{int,uint}( 3, "3") ==> no +base_string_to_{int,uint}( 8, "7") ==> 7 +base_string_to_{int,uint}( 8, "8") ==> no +base_string_to_{int,uint}( 9, "8") ==> 8 +base_string_to_{int,uint}( 9, "9") ==> no +base_string_to_{int,uint}( 10, "9") ==> 9 +base_string_to_{int,uint}( 10, "a") ==> no +base_string_to_{int,uint}( 10, "A") ==> no +base_string_to_{int,uint}( 11, "a") ==> 10 +base_string_to_{int,uint}( 11, "A") ==> 10 +base_string_to_{int,uint}( 11, "b") ==> no +base_string_to_{int,uint}( 11, "B") ==> no +base_string_to_{int,uint}( 16, "f") ==> 15 +base_string_to_{int,uint}( 16, "g") ==> no +base_string_to_{int,uint}( 16, "G") ==> no +base_string_to_{int,uint}( 17, "g") ==> 16 +base_string_to_{int,uint}( 17, "h") ==> no +base_string_to_{int,uint}( 35, "y") ==> 34 +base_string_to_{int,uint}( 35, "z") ==> no +base_string_to_{int,uint}( 35, "Z") ==> no +base_string_to_{int,uint}( 36, "z") ==> 35 +base_string_to_{int,uint}( 36, "Z") ==> 35 +base_string_to_{int,uint}( 2, "102") ==> no +base_string_to_{int,uint}( 8, "178") ==> no +base_string_to_{int,uint}( 16, "1fg") ==> no ### Non-digit characters ### -base_string_to_int(10, " 1") ==> no -base_string_to_int(10, "1 ") ==> no -base_string_to_int(10, "1 2") ==> no -base_string_to_int(10, "1.0") ==> no -base_string_to_int(10, "1,000") ==> no -base_string_to_int(10, "1_000") ==> no -base_string_to_int(10, "1e5") ==> no -base_string_to_int(16, "0x10") ==> no -base_string_to_int(10, "\t1") ==> no -base_string_to_int(10, "1\n") ==> no -base_string_to_int(36, "1!") ==> no -base_string_to_int(10, "3") ==> no +base_string_to_{int,uint}( 10, " 1") ==> no +base_string_to_{int,uint}( 10, "1 ") ==> no +base_string_to_{int,uint}( 10, "1 2") ==> no +base_string_to_{int,uint}( 10, "1.0") ==> no +base_string_to_{int,uint}( 10, "1,000") ==> no +base_string_to_{int,uint}( 10, "1_000") ==> no +base_string_to_{int,uint}( 10, "1e5") ==> no +base_string_to_{int,uint}( 16, "0x10") ==> no +base_string_to_{int,uint}( 10, "\t1") ==> no +base_string_to_{int,uint}( 10, "1\n") ==> no +base_string_to_{int,uint}( 36, "1!") ==> no +base_string_to_{int,uint}( 10, "3") ==> no ### Signs in the wrong place ### -base_string_to_int(10, "1-") ==> no -base_string_to_int(10, "1+") ==> no -base_string_to_int(10, "1-2") ==> no -base_string_to_int(10, "12-34") ==> no -base_string_to_int(10, "--1") ==> no -base_string_to_int(10, "++1") ==> no -base_string_to_int(10, "-1-") ==> no +base_string_to_{int,uint}( 10, "1-") ==> no +base_string_to_{int,uint}( 10, "1+") ==> no +base_string_to_{int,uint}( 10, "1-2") ==> no +base_string_to_{int,uint}( 10, "12-34") ==> no +base_string_to_{int,uint}( 10, "--1") ==> no +base_string_to_{int,uint}( 10, "++1") ==> no +base_string_to_{int,uint}( 10, "-1-") ==> no ### The string "10" in every base ### -base_string_to_int(2, "10") ==> 2 -base_string_to_int(3, "10") ==> 3 -base_string_to_int(4, "10") ==> 4 -base_string_to_int(5, "10") ==> 5 -base_string_to_int(6, "10") ==> 6 -base_string_to_int(7, "10") ==> 7 -base_string_to_int(8, "10") ==> 8 -base_string_to_int(9, "10") ==> 9 -base_string_to_int(10, "10") ==> 10 -base_string_to_int(11, "10") ==> 11 -base_string_to_int(12, "10") ==> 12 -base_string_to_int(13, "10") ==> 13 -base_string_to_int(14, "10") ==> 14 -base_string_to_int(15, "10") ==> 15 -base_string_to_int(16, "10") ==> 16 -base_string_to_int(17, "10") ==> 17 -base_string_to_int(18, "10") ==> 18 -base_string_to_int(19, "10") ==> 19 -base_string_to_int(20, "10") ==> 20 -base_string_to_int(21, "10") ==> 21 -base_string_to_int(22, "10") ==> 22 -base_string_to_int(23, "10") ==> 23 -base_string_to_int(24, "10") ==> 24 -base_string_to_int(25, "10") ==> 25 -base_string_to_int(26, "10") ==> 26 -base_string_to_int(27, "10") ==> 27 -base_string_to_int(28, "10") ==> 28 -base_string_to_int(29, "10") ==> 29 -base_string_to_int(30, "10") ==> 30 -base_string_to_int(31, "10") ==> 31 -base_string_to_int(32, "10") ==> 32 -base_string_to_int(33, "10") ==> 33 -base_string_to_int(34, "10") ==> 34 -base_string_to_int(35, "10") ==> 35 -base_string_to_int(36, "10") ==> 36 +base_string_to_{int,uint}( 2, "10") ==> 2 +base_string_to_{int,uint}( 3, "10") ==> 3 +base_string_to_{int,uint}( 4, "10") ==> 4 +base_string_to_{int,uint}( 5, "10") ==> 5 +base_string_to_{int,uint}( 6, "10") ==> 6 +base_string_to_{int,uint}( 7, "10") ==> 7 +base_string_to_{int,uint}( 8, "10") ==> 8 +base_string_to_{int,uint}( 9, "10") ==> 9 +base_string_to_{int,uint}( 10, "10") ==> 10 +base_string_to_{int,uint}( 11, "10") ==> 11 +base_string_to_{int,uint}( 12, "10") ==> 12 +base_string_to_{int,uint}( 13, "10") ==> 13 +base_string_to_{int,uint}( 14, "10") ==> 14 +base_string_to_{int,uint}( 15, "10") ==> 15 +base_string_to_{int,uint}( 16, "10") ==> 16 +base_string_to_{int,uint}( 17, "10") ==> 17 +base_string_to_{int,uint}( 18, "10") ==> 18 +base_string_to_{int,uint}( 19, "10") ==> 19 +base_string_to_{int,uint}( 20, "10") ==> 20 +base_string_to_{int,uint}( 21, "10") ==> 21 +base_string_to_{int,uint}( 22, "10") ==> 22 +base_string_to_{int,uint}( 23, "10") ==> 23 +base_string_to_{int,uint}( 24, "10") ==> 24 +base_string_to_{int,uint}( 25, "10") ==> 25 +base_string_to_{int,uint}( 26, "10") ==> 26 +base_string_to_{int,uint}( 27, "10") ==> 27 +base_string_to_{int,uint}( 28, "10") ==> 28 +base_string_to_{int,uint}( 29, "10") ==> 29 +base_string_to_{int,uint}( 30, "10") ==> 30 +base_string_to_{int,uint}( 31, "10") ==> 31 +base_string_to_{int,uint}( 32, "10") ==> 32 +base_string_to_{int,uint}( 33, "10") ==> 33 +base_string_to_{int,uint}( 34, "10") ==> 34 +base_string_to_{int,uint}( 35, "10") ==> 35 +base_string_to_{int,uint}( 36, "10") ==> 36 ### Invalid bases ### -base_string_to_int(1, "1") ==> exception -base_string_to_int(0, "1") ==> exception -base_string_to_int(-1, "1") ==> exception -base_string_to_int(37, "1") ==> exception -base_string_to_int(100, "1") ==> exception +base_string_to_{int,uint}( 1, "1") ==> exception +base_string_to_{int,uint}( 0, "1") ==> exception +base_string_to_{int,uint}( -1, "1") ==> exception +base_string_to_{int,uint}( 37, "1") ==> exception +base_string_to_{int,uint}(100, "1") ==> exception -### det_base_string_to_int ### +### det_base_string_to_{int,uint} ### -det_base_string_to_int(10, "123") ==> 123 -det_base_string_to_int(16, "ff") ==> 255 -det_base_string_to_int(10, "") ==> exception -det_base_string_to_int(10, "12a") ==> exception -det_base_string_to_int(1, "1") ==> exception +det_base_string_to_{int,uint}(10, "123") ==> 123 +det_base_string_to_{int,uint}(16, "ff") ==> 255 +det_base_string_to_{int,uint}(10, "") ==> exception +det_base_string_to_{int,uint}(10, "12a") ==> exception +det_base_string_to_{int,uint}( 1, "1") ==> exception -### to_int ### +### to_{int,uint} ### -to_int("123") ==> 123 -to_int("-123") ==> -123 -to_int("") ==> no -to_int("0x10") ==> no -to_int(" 1") ==> no +to_{int,uint}( "123") ==> 123 +to_{int,uint}("-123") ==> int = -123, uint = no +to_{int,uint}( "") ==> no +to_{int,uint}("0x10") ==> no +to_{int,uint}( " 1") ==> no diff --git a/tests/hard_coded/base_string_to_int.m b/tests/hard_coded/base_string_to_int.m index 771767ce0..8048e9092 100644 --- a/tests/hard_coded/base_string_to_int.m +++ b/tests/hard_coded/base_string_to_int.m @@ -2,9 +2,11 @@ % vim: ts=4 sw=4 et ft=mercury %---------------------------------------------------------------------------% % -% Test the non-overflow behaviour of string.base_string_to_int/3. -% (The overflow behaviour of this predicate is tested separately, by -% ../general/test_string_to_int_overflow.m.) +% Test the non-overflow behaviour of string.base_string_to_int/3 and +% string.base_string_to_uint/3. +% (The overflow behaviour of these predicates is tested separately, by +% ../general/test_string_to_int_overflow.m and string_to_uint_overflow.m +% respectively.) % %---------------------------------------------------------------------------% @@ -30,13 +32,27 @@ %---------------------------------------------------------------------------% main(!IO) :- - header("Empty, blank and sign-only strings", !IO), + header("Empty strings", !IO), test(10, "", !IO), test(2, "", !IO), test(36, "", !IO), + io.nl(!IO), + + header("Blank strings", !IO), test(10, " ", !IO), + test(10, " ", !IO), + test(10, "\t", !IO), + test(10, "\n", !IO), + test(10, " \t ", !IO), test(2, " ", !IO), test(36, " ", !IO), + io.nl(!IO), + + header("Signs", !IO), + test(10, "-1", !IO), + test(10, "+1", !IO), + test(10, "-0", !IO), + test(10, "+0", !IO), test(10, "-", !IO), test(10, "+", !IO), test(16, "-", !IO), @@ -45,10 +61,6 @@ main(!IO) :- test(10, "++", !IO), test(10, "+-1", !IO), test(10, "-+1", !IO), - test(10, " ", !IO), - test(10, "\t", !IO), - test(10, "\n", !IO), - test(10, " \t ", !IO), test(10, "- ", !IO), test(10, "+ ", !IO), io.nl(!IO), @@ -150,9 +162,9 @@ main(!IO) :- list.foldl(test_10_in_base, 2 .. 36, !IO), io.nl(!IO), - % base_string_to_int/3 throws an exception if the base is not in 2..36. - % It checks the base before it looks at the string, so the string is - % irrelevant in these tests. + % Both base_string_to_int/3 and base_string_to_uint/3 throw an exception if + % the base is not in 2..36. They check the base before they look at the + % string, so the string is irrelevant in these tests. header("Invalid bases", !IO), test(1, "1", !IO), @@ -162,7 +174,7 @@ main(!IO) :- test(100, "1", !IO), io.nl(!IO), - header("det_base_string_to_int", !IO), + header("det_base_string_to_{int,uint}", !IO), test_det(10, "123", !IO), test_det(16, "ff", !IO), test_det(10, "", !IO), @@ -171,8 +183,9 @@ main(!IO) :- io.nl(!IO), % to_int/2 is base_string_to_int/3 with the base fixed at 10. + % to_uint/2 is base_string_to_uint/3 with the base fixed at 10. - header("to_int", !IO), + header("to_{int,uint}", !IO), test_to_int("123", !IO), test_to_int("-123", !IO), test_to_int("", !IO), @@ -191,14 +204,17 @@ test_10_in_base(Base, !IO) :- % test(Base, Str, !IO): % - % Test string.base_string_to_int(Base, Str, Int), writing out the call - % and then its result: the value of Int if the call succeeds, "no" if - % it fails, or "exception" if it throws. + % Test string.base_string_to_int(Base, Str, Int) and + % string.base_string_to_uint(Base, Str, UInt) writing out + % the call then results: the numeric value of the Int / UInt if both + % calls succeed, "no" if they fail, or "exception" if they throw + % an exception. If the results differ between the signed and signed + % version, write out both results. % :- pred test(int::in, string::in, io::di, io::uo) is cc_multi. test(Base, Str, !IO) :- - io.format("base_string_to_int(%d, %s) ==> ", + io.format("base_string_to_{int,uint}(%3d, %8s) ==> ", [i(Base), s(string(Str))], !IO), ( try [] ( if string.base_string_to_int(Base, Str, Int0) then @@ -209,36 +225,83 @@ test(Base, Str, !IO) :- then ( MaybeInt = yes(Int), - io.write_line(Int, !IO) + IntResult = int_to_string(Int) ; MaybeInt = no, - io.write_string("no\n", !IO) + IntResult = "no" ) catch_any _ -> - io.write_string("exception\n", !IO) + IntResult = "exception" + ), + ( try [] + ( if string.base_string_to_uint(Base, Str, UInt0) then + MaybeUInt = yes(UInt0) + else + MaybeUInt = no + ) + then + ( + MaybeUInt = yes(UInt), + UIntResult = uint_to_string(UInt) + ; + MaybeUInt = no, + UIntResult = "no" + ) + catch_any _ -> + UIntResult = "exception" + ), + ( if IntResult = UIntResult then + io.print_line(IntResult, !IO) + else + io.format("int = %3s, uint = %3s\n", + [s(IntResult), s(UIntResult)], !IO) ). :- pred test_det(int::in, string::in, io::di, io::uo) is cc_multi. test_det(Base, Str, !IO) :- - io.format("det_base_string_to_int(%d, %s) ==> ", + io.format("det_base_string_to_{int,uint}(%2d, %5s) ==> ", [i(Base), s(string(Str))], !IO), ( try [] Int = string.det_base_string_to_int(Base, Str) then - io.write_line(Int, !IO) + IntResult = int_to_string(Int) catch_any _ -> - io.write_string("exception\n", !IO) + IntResult = "exception" + ), + ( try [] + UInt = string.det_base_string_to_uint(Base, Str) + then + UIntResult = uint_to_string(UInt) + catch_any _ -> + UIntResult = "exception" + ), + ( if IntResult = UIntResult then + io.print_line(IntResult, !IO) + else + io.format("int = %3s, uint = %3s\n", + [s(IntResult), s(UIntResult)], !IO) ). :- pred test_to_int(string::in, io::di, io::uo) is det. test_to_int(Str, !IO) :- - io.format("to_int(%s) ==> ", [s(string(Str))], !IO), + io.format("to_{int,uint}(%6s) ==> ", [s(string(Str))], !IO), ( if string.to_int(Str, Int) then - io.write_line(Int, !IO) + IntResult = int_to_string(Int) + else + IntResult = "no" + ), + ( if string.to_uint(Str, UInt) then + UIntResult = uint_to_string(UInt) + else + UIntResult = "no" + ), + ( if IntResult = UIntResult then + io.print_line(IntResult, !IO) else - io.write_string("no\n", !IO) + io.format("int = %3s, uint = %3s\n", + [s(IntResult), s(UIntResult)], !IO) ). %---------------------------------------------------------------------------%