]> git.mdlowis.com Git - archive/tide-ocaml.git/commitdiff
fixed some bugs in utf8 decoding
authorMichael D. Lowis <mike.lowis@gentex.com>
Tue, 19 Dec 2017 14:02:22 +0000 (09:02 -0500)
committerMichael D. Lowis <mike.lowis@gentex.com>
Tue, 19 Dec 2017 14:02:22 +0000 (09:02 -0500)
lib/cfg.ml
lib/rope.ml
lib/rope.mli
tests/rope_tests.ml

index a107b570e1894280a8322d3ff4250d2e7c7e3ccc..1f5a30c400623ca396f24e58fb97d04957832859 100644 (file)
@@ -27,7 +27,7 @@ let cmd_tags = strvar "tide.ui.font"
     "Quit Undo Redo Cut Copy Paste | Send Find "
 
 (* font settings *)
-let font = strvar "tide.ui.tags.edit" "Verdana:size=11"
+let font = strvar "tide.ui.tags.edit" "Verdana:size=10"
 let line_spacing = intvar "tide.ui.line_spacing" 1
 
 (* user interface related options *)
index 402a90022309ba76563adc294728d1b30f97bb77..1daa9434f7e56f3b89dc9c945651f1a5a89517e9 100644 (file)
@@ -70,26 +70,30 @@ let rec utfbeg rope pos =
   else
     pos
 
+let runeerr msg =
+  print_endline msg; 0xFFFD
+
 let rec decode rope i len rune =
-  let byte = (getc rope i) in
-  if len == 0 then
-    (rune, i)
-  else if not (is_cont_byte byte) then
-    (0xFFFD, i)
+  if len == 0 then (rune, i)
   else
-    decode rope (i + 1) (len - 1) ((rune lsl 6) lor (byte land 0x3F))
+    let byte = (getc rope i) in
+    if not (is_cont_byte byte) then
+      (runeerr "missing cont. byte", i)
+    else
+      decode rope (i + 1) (len - 1) ((rune lsl 6) lor (byte land 0x3F))
 
 let get_rune rope i =
   let byte = (getc rope i) in
-  if byte < 128 then
-    (byte, i+1)
-  else if byte >= 245 || byte == 192 || byte == 193 then
-    (0xFFFD, i+1)
+  if byte == 192 || byte == 193 then
+    (runeerr "invalid utf8 byte", i + 1)
   else
-    let byte = (getc rope i) in
-    let len  = (utfseq byte) in
+    let byte = (getc rope i) and len = (utfseq byte) in
     try decode rope (i + 1) (len - 1) (byte land utf8_seqmask.(len))
-    with _ -> (0xFFFD, i + 1)
+    with e ->
+      (runeerr "failure decoding", i + 1)
+
+let getr rope i =
+  let rune, next = get_rune rope i in rune
 
 let rec each_rune_rec fn rope pos =
   if pos < (length rope) then
index 5255852abb7965cefcae5b8522f554d47b018303..51389bdd4b79c5f8f55f2eda191b6c58ba8159a2 100644 (file)
@@ -25,6 +25,7 @@ val iteri : (int -> rune -> bool) -> rope -> int -> unit
 val each_rune : (int -> rune -> bool) -> rope -> int -> unit
 
 val getc : rope -> int -> rune
+val getr : rope -> int -> rune
 (*
 val putc : rope -> int -> rune -> rope
 *)
index 5cec04574b369d8dd465859f056597937ca075a7..4a788114a643707c22fd2c35a324012a15e50a18 100644 (file)
@@ -239,3 +239,30 @@ let () = (* to_eol() tests *)
     assert( (to_eol rope 1) == 4 );
   );
   ()
+
+let () =
+  test "getr : " (fun () ->
+    let rope = from_string "\x7F" in
+    assert( (getr rope 0) == 0x7F );
+  );
+  test "getr : " (fun () ->
+    let rope = from_string "\xDF\xBF" in
+    assert( (getr rope 0) == 0x7FF );
+  );
+  test "getr : " (fun () ->
+    let rope = from_string "\xEF\xBF\xBF" in
+    assert( (getr rope 0) == 0xFFFF );
+  );
+  test "getr : " (fun () ->
+    let rope = from_string "\xF7\xBF\xBF\xBF" in
+    assert( (getr rope 0) == 0x1FFFFF );
+  );
+  test "getr : " (fun () ->
+    let rope = from_string "\xFB\xBF\xBF\xBF\xBF" in
+    assert( (getr rope 0) == 0x3FFFFFF );
+  );
+  test "getr : " (fun () ->
+    let rope = from_string "\xFD\xBF\xBF\xBF\xBF\xBF" in
+    assert( (getr rope 0) == 0x7FFFFFFF );
+  );
+  ()