[m-rev.] for post-commit review: fix string.from_char_list in C# and Java grades

Julien Fischer jfischer at opturion.com
Thu Jul 3 17:47:21 AEST 2014


For post-commit review by anyone.

Branches: 14.01, master

-------------------------------------

Fix the behaviour of string.from_char_list in C# and Java grades.

The predicate string.from_char_list and string.from_reverse_char_list should
throw an exception if their input lists contain the null character.  This
was not done for the C# and Java grades for the former, and the C# grade for
the latter.
(This fixes the failure of tests/hard_coded/null_char in the C# grade and
almost fixes it for the Java grade.)

library/string.m:
 	Make the above predicates throw an exception if their input lists
 	contain the null character.

NEWS:
 	Announce the above fix.

Julien.

diff --git a/NEWS b/NEWS
index ed2121e..77c1449 100644
--- a/NEWS
+++ b/NEWS
@@ -25,6 +25,10 @@ This is a bug-fix release.
    correctly with the non-C backends.
  * A bug that caused io.write_float/[34] to append ".0" to float special values
    has been fixed.  This bug affected the C and C# backends.
+* In the C# and Java grades, the predicate string.from_char_list now
+  implements the documented behaviour for input lists containing null
+  characters (i.e. it throws an exception).
+  Likewise, for string.from_reverse_char_list in the C# grade.

  Changes to the Mercury compiler:

diff --git a/library/string.m b/library/string.m
index 2688991..03354cc 100644
--- a/library/string.m
+++ b/library/string.m
@@ -1787,10 +1787,14 @@ string.from_char_list(Chars::in, Str::uo) :-
      [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail,
          does_not_affect_liveness],
  "
+    SUCCESS_INDICATOR = true;
      System.Text.StringBuilder sb = new System.Text.StringBuilder();
      while (!list.is_empty(CharList)) {
          int cp = (int) list.det_head(CharList);
-        if (cp <= 0xffff) {
+        if (cp == 0x0000) {
+            SUCCESS_INDICATOR = false;
+            break;
+        } else if (cp <= 0xffff) {
              sb.Append((char) cp);
          } else {
              sb.Append(System.Char.ConvertFromUtf32(cp));
@@ -1798,7 +1802,6 @@ string.from_char_list(Chars::in, Str::uo) :-
          CharList = list.det_tail(CharList);
      }
      Str = sb.ToString();
-    SUCCESS_INDICATOR = true;
  ").

  :- pragma foreign_proc("Java",
@@ -1808,8 +1811,12 @@ string.from_char_list(Chars::in, Str::uo) :-
  "
      java.lang.StringBuilder sb = new StringBuilder();
      Iterable<Integer> iterable = new list.ListIterator<Integer>(CharList);
+    SUCCESS_INDICATOR = true;
      for (int c : iterable) {
-        if (c <= 0xffff) {
+        if (c == 0x0000) {
+            SUCCESS_INDICATOR = false;
+            break;
+        } else if (c <= 0xffff) {
              /* Fast path. */
              sb.append((char) c);
          } else {
@@ -1817,7 +1824,6 @@ string.from_char_list(Chars::in, Str::uo) :-
          }
      }
      Str = sb.toString();
-    SUCCESS_INDICATOR = true;
  ").

  :- pragma foreign_proc("Erlang",
@@ -1932,9 +1938,13 @@ string.from_rev_char_list(Chars, Str) :-

      char[] arr = new char[size];
      list_ptr = Chars;
+    SUCCESS_INDICATOR = true;
      while (!list.is_empty(list_ptr)) {
          int c = (int) list.det_head(list_ptr);
-        if (c <= 0xffff) {
+        if (c == 0x0000) {
+            SUCCESS_INDICATOR = false;
+            break;
+        } else if (c <= 0xffff) {
              arr[--size] = (char) c;
          } else {
              string s = System.Char.ConvertFromUtf32(c);
@@ -1945,7 +1955,6 @@ string.from_rev_char_list(Chars, Str) :-
      }

      Str = new string(arr);
-    SUCCESS_INDICATOR = true;
  ").

  string.semidet_from_rev_char_list(Chars::in, Str::uo) :-



More information about the reviews mailing list