text: (* test/bytechar.sml -- test cases for Byte and Char, suitable for ASCII
     PS 1994-12-10, 1995-05-11, 1995-11-10, 1996-09-30 *)
  
  use "auxil.sml";
  
  local 
  
  in 
  val test1 = checkrange (0,255) (fn i => 
      (Word8.toInt o Byte.charToByte o Byte.byteToChar o Word8.fromInt) i = i);
  
  val test2 = checkrange (0,Char.maxOrd) (fn i => 
      (Word8.toInt o Byte.charToByte o Char.chr) i = i);
  
  val test3 = checkrange (0,255) 
      (fn i => (Char.ord o Byte.byteToChar o Word8.fromInt) i = i);
  
  val test4 = checkrange (0, Char.maxOrd) 
      (fn i => (Char.ord o Char.chr) i = i);
  
  val test5 = (Char.chr ~1 seq "WRONG") handle Chr => "OK" | _ => "WRONG";
  
  val test6 = (Char.chr (Char.maxOrd+1) seq "WRONG") 
              handle Chr => "OK" | _ => "WRONG";
  	
  val test7 = check("" = Byte.bytesToString (Word8Vector.fromList []));
  
  val test8 = 
      check("ABDC" = 
  	  (Byte.bytesToString o Word8Vector.fromList o map Word8.fromInt)
  	   [65, 66, 68, 67]);
  
  val test9 = check("" = Byte.unpackString(Word8Array.fromList [], 0, SOME 0));
  
  local 
      val arr = Word8Array.tabulate(10, fn i => Word8.fromInt(i+65))
  in
  val test10a = check("" = Byte.unpackString(arr, 0, SOME 0));
  val test10b = check("" = Byte.unpackString(arr, 10, SOME 0) 
   		   andalso "" = Byte.unpackString(arr, 10, NONE));
  val test10c = check("BCDE" = Byte.unpackString(arr, 1, SOME 4));
  val test10d = (Byte.unpackString(arr, ~1, SOME 0) seq "WRONG")
                handle Subscript => "OK" | _ => "WRONG";
  val test10e = (Byte.unpackString(arr, 11, SOME 0) seq "WRONG")
                handle Subscript => "OK" | _ => "WRONG";
  val test10f = (Byte.unpackString(arr, 0, SOME ~1) seq "WRONG")
                handle Subscript => "OK" | _ => "WRONG";
  val test10g = (Byte.unpackString(arr, 0, SOME 11) seq "WRONG")
                handle Subscript => "OK" | _ => "WRONG";
  val test10h = (Byte.unpackString(arr, 10, SOME 1) seq "WRONG")
                handle Subscript => "OK" | _ => "WRONG";
  val test10i = (Byte.unpackString(arr, ~1, NONE) seq "WRONG")
                handle Subscript => "OK" | _ => "WRONG";
  val test10j = (Byte.unpackString(arr, 11, NONE) seq "WRONG")
                handle Subscript => "OK" | _ => "WRONG";
  end
  
  local 
      val vec = Word8Vector.tabulate(10, fn i => Word8.fromInt(i+65))
  in
  val test11a = check("" = Byte.unpackStringVec(vec, 0, SOME 0));
  val test11b = check("" = Byte.unpackStringVec(vec, 10, SOME 0) 
   		   andalso "" = Byte.unpackStringVec(vec, 10, NONE));
  val test11c = check("BCDE" = Byte.unpackStringVec(vec, 1, SOME 4));
  val test11d = (Byte.unpackStringVec(vec, ~1, SOME 0) seq "WRONG")
                handle Subscript => "OK" | _ => "WRONG";
  val test11e = (Byte.unpackStringVec(vec, 11, SOME 0) seq "WRONG")
                handle Subscript => "OK" | _ => "WRONG";
  val test11f = (Byte.unpackStringVec(vec, 0, SOME ~1) seq "WRONG")
                handle Subscript => "OK" | _ => "WRONG";
  val test11g = (Byte.unpackStringVec(vec, 0, SOME 11) seq "WRONG")
                handle Subscript => "OK" | _ => "WRONG";
  val test11h = (Byte.unpackStringVec(vec, 10, SOME 1) seq "WRONG")
                handle Subscript => "OK" | _ => "WRONG";
  val test11i = (Byte.unpackStringVec(vec, ~1, NONE) seq "WRONG")
                handle Subscript => "OK" | _ => "WRONG";
  val test11j = (Byte.unpackStringVec(vec, 11, NONE) seq "WRONG")
                handle Subscript => "OK" | _ => "WRONG";
  end
  
  val test18 = check(not (Char.contains "" (Char.chr 65))
                     andalso not (Char.contains "aBCDE" (Char.chr 65))
                     andalso (Char.contains "ABCD" (Char.chr 67))
  		   andalso not (Char.contains "" #"\000")
  		   andalso not (Char.contains "" #"\255")
  		   andalso not (Char.contains "azAZ09" #"\000")
  		   andalso not (Char.contains "azAZ09" #"\255"));
  
  val test19 = check(Char.notContains "" (Char.chr 65)
                     andalso Char.notContains "aBCDE" (Char.chr 65)
                     andalso not (Char.notContains "ABCD" (Char.chr 67))
                     andalso Char.notContains "" #"\000"
                     andalso Char.notContains "" #"\255"
                     andalso Char.notContains "azAZ09" #"\000"
                     andalso Char.notContains "azAZ09" #"\255");
  
  val test20 = check(Char.ord Char.maxChar = Char.maxOrd);
  
  local 
  fun mycontains s c = 
      let val stop = String.size s
  	fun h i = i < stop andalso (c = String.sub(s, i) orelse h(i+1))
      in h 0 end;
  
  (* Check that p(c) = (mycontains s c) for all characters: *)
  fun equivalent p s = 
      let fun h n =
  	n > 255 orelse 
  	(p (chr n) = mycontains s (chr n)) andalso h(n+1)
      in h 0 end
  
  fun checkset p s = check'(fn _ => equivalent p s);
  
  val graphchars = "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\
   \[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
  
  val ascii = "\^@\^A\^B\^C\^D\^E\^F\^G\^H\t\n\^K\^L\^M\^N\^O\^P\
   \\^Q\^R\^S\^T\^U\^V\^W\^X\^Y\^Z\^[\^\\^]\^^\^_\
   \ !\"#$%&'()*+,-./0123456789:;<=>?@\
   \ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\127" 
  
  val lowerascii = "\^@\^A\^B\^C\^D\^E\^F\^G\^H\t\n\^K\^L\^M\^N\^O\^P\
   \\^Q\^R\^S\^T\^U\^V\^W\^X\^Y\^Z\^[\^\\^]\^^\^_\
   \ !\"#$%&'()*+,-./0123456789:;<=>?@\
   \abcdefghijklmnopqrstuvwxyz[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\127" 
  
  val upperascii = "\^@\^A\^B\^C\^D\^E\^F\^G\^H\t\n\^K\^L\^M\^N\^O\^P\
   \\^Q\^R\^S\^T\^U\^V\^W\^X\^Y\^Z\^[\^\\^]\^^\^_\
   \ !\"#$%&'()*+,-./0123456789:;<=>?@\
   \ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~\127" 
  
  val allchars = 
      let fun h 0 res = chr 0 :: res
  	  | h n res = h (n-1) (chr n :: res)
      in h 255 [] end
  
  open Char
  in
  
  val test21 = 
      checkset isLower "abcdefghijklmnopqrstuvwxyz";
  val test22 = 
      checkset isUpper "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  val test23 = 
      checkset isDigit "0123456789";
  val test24 = 
      checkset isAlpha "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
  val test25 = 
      checkset isHexDigit "0123456789abcdefABCDEF";
  val test26 = 
      checkset isAlphaNum 
         "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
  val test27 = 
      checkset isPrint (" " ^ graphchars)
  val test28 = 
      checkset isSpace " \009\010\011\012\013";
  val test29 = 
      checkset isGraph graphchars
  val test30 = 
      checkset isAscii ascii
  
  val test31 = 
      check'(fn _ => map toLower (explode ascii) = explode lowerascii)
  val test32 = 
      check'(fn _ => map toUpper (explode ascii) = explode upperascii)
  val test33 = 
      check'(fn _ => 
  	   map toUpper (explode graphchars)
  	   seq map toLower (explode graphchars)
  	   seq true)
  
  val test34a =
      check'(fn _ => 
  	   map pred (List.drop(allchars, 1)) = List.take(allchars, 255));
  val test34b = (pred minChar seq "WRONG")
                handle Chr => "OK" | _ => "WRONG";
  val test35a =
      check'(fn _ => 
  	   map succ (List.take(allchars, 255)) = List.drop(allchars, 1));
  val test35b = (succ maxChar seq "WRONG")
                handle Chr => "OK" | _ => "WRONG";
  end
  
  
  (* Test cases for SML character escape functions. *)
  
  val test36 = 
      let fun chk (arg, res) = Char.toString arg = res
      in check'(fn _ => List.all chk 
  	      [(#"\000", "\\^@"),
  	       (#"\001", "\\^A"),
  	       (#"\006", "\\^F"),
  	       (#"\007", "\\a"),
  	       (#"\008", "\\b"),
  	       (#"\009", "\\t"),
  	       (#"\010", "\\n"),
  	       (#"\011", "\\v"),
  	       (#"\012", "\\f"),
  	       (#"\013", "\\r"),
  	       (#"\014", "\\^N"),
  	       (#"\031", "\\^_"),
  	       (#"\032", " "),
  	       (#"\126", "~"),
  	       (#"\\", "\\\\"),
  	       (#"\"", "\\\""),
  	       (#"A", "A"),
  	       (#"\127", "\\127"),
  	       (#"\128", "\\128"),
  	       (#"\255", "\\255")])
      end;
  
  val test37 = 
      let val chars = List.tabulate(256, chr)
  	fun chk c = Char.fromString(Char.toString c) = SOME c
      in check'(fn _ => List.all chk chars) end
  
  val test38 =   		     
      let fun chkFromString (arg, res) = Char.fromString arg = SOME res
  	val argResList = 
  	    [("A", #"A"),
  	     ("z", #"z"),
  	     ("@", #"@"),
  	     ("~", #"~"),
  	     ("\\a", #"\007"),
  	     ("\\b", #"\008"),
  	     ("\\t", #"\009"),
  	     ("\\n", #"\010"),
  	     ("\\v", #"\011"),
  	     ("\\f", #"\012"),
  	     ("\\r", #"\013"),
  	     ("\\\\", #"\\"),
  	     ("\\\"", #"\""),
  	     ("\\^@", #"\000"),
  	     ("\\^A", #"\001"),
  	     ("\\^Z", #"\026"),
  	     ("\\^_", #"\031"), 
  	     ("\\000", #"\000"),
  	     ("\\097", #"a"),
  	     ("\\255", #"\255"),
  	     ("\\   \t\n\n \\A", #"A"),
  	     ("\\   \t\n\n \\z", #"z"),
  	     ("\\   \t\n\n \\@", #"@"),
  	     ("\\   \t\n\n \\~", #"~"),
  	     ("\\   \t\n\n \\\\n", #"\n"),
  	     ("\\   \t\n\n \\\\t", #"\t"),
  	     ("\\   \t\n\n \\\\\\", #"\\"),
  	     ("\\   \t\n\n \\\\\"", #"\""),
  	     ("\\   \t\n\n \\\\^@", #"\000"),
  	     ("\\   \t\n\n \\\\^A", #"\001"),
  	     ("\\   \t\n\n \\\\^Z", #"\026"),
  	     ("\\   \t\n\n \\\\^_", #"\031"), 
  	     ("\\   \t\n\n \\\\000", #"\000"),
  	     ("\\   \t\n\n \\\\097", #"a"),
  	     ("\\   \t\n\n \\\\255", #"\255")]
      in 
  	check'(fn _ => List.all chkFromString argResList)
      end;
  
  val test39 = 
      check'(fn _ => List.all (fn arg => Char.fromString arg = NONE)
  	   ["\\",
  	    "\\c",
  	    "\\F",
  	    "\\e",
  	    "\\g",
  	    "\\N",
  	    "\\T",
  	    "\\1",
  	    "\\11",
  	    "\\256",
  	    "\\-65",
  	    "\\~65",
  	    "\\?",
  	    "\\^`",
  	    "\\^a",
  	    "\\^z",
  	    "\\   a",
  	    "\\   a\\B",
  	    "\\   \\"]);
  
  (* Test cases for C string escape functions *)
  
  val test40 = 
      let val chars = List.tabulate(256, chr)
      in check'(fn _ => 
  	      List.map SOME chars 
  	      = List.map Char.fromCString (List.map Char.toCString chars))
      end;
  
  val test41 = 
      let val argResList = 
  	    [(#"\010", "\\n"),
  	     (#"\009", "\\t"),
  	     (#"\011", "\\v"),
  	     (#"\008", "\\b"),
  	     (#"\013", "\\r"),
  	     (#"\012", "\\f"),
  	     (#"\007", "\\a"),
  	     (#"\\", "\\\\"),
  	     (#"?", "\\?"),
  	     (#"'", "\\'"),
  	     (#"\"", "\\\"")]
      in
  	check'(fn _ => 
  	       List.all (fn (arg, res) => Char.toCString arg = res) argResList)
      end;
  
  val test42 = 
      let fun checkFromCStringSucc (arg, res) = 
              str (valOf (Char.fromCString arg)) = res
  	val argResList = 
  	    [("\\n", "\010"),
  	     ("\\t", "\009"),
  	     ("\\v", "\011"),
  	     ("\\b", "\008"),
  	     ("\\r", "\013"),
  	     ("\\f", "\012"),
  	     ("\\a", "\007"),
  	     ("\\\\",  "\\"),
  	     ("\\?", "?"),
  	     ("\\'", "'"),
  	     ("\\\"", "\""),
  	     ("\\1", "\001"),
  	     ("\\11", "\009"),
  	     ("\\111", "\073"),
  	     ("\\1007", "\064"),
  	     ("\\100A", "\064"),
  	     ("\\0",   "\000"),
  	     ("\\377", "\255"),
  	     ("\\18", "\001"),
  	     ("\\178", "\015"),
  	     ("\\1C", "\001"),
  	     ("\\17C", "\015"),
  	     ("\\x0", "\000"),
  	     ("\\xff", "\255"),
  	     ("\\xFF", "\255"),
  	     ("\\x1", "\001"),
  	     ("\\x11", "\017"),
  	     ("\\xag", "\010"),
  	     ("\\xAAg", "\170"),
  	     ("\\x0000000a", "\010"),
  	     ("\\x0000000a2", "\162"),
  	     ("\\x0000000ag", "\010"),
  	     ("\\x0000000A", "\010"),
  	     ("\\x0000000A2", "\162"),
  	     ("\\x0000000Ag", "\010"),
  	     ("\\x00000000000000000000000000000000000000000000000000000000000000011+",
  	      "\017")]
      in 
  	check'(fn _ => List.all checkFromCStringSucc argResList)
      end;
  
  val test43 = 
      let fun checkFromCStringFail arg = Char.fromCString arg = NONE
      in
  	check'(fn _ => List.all checkFromCStringFail 
  	       ["\\",
  		"\\X",
  		"\\=",
  		"\\400",
  		"\\777",
  		"\\8",
  		"\\9",
  		"\\c",
  		"\\d",
  		"\\x",
  		"\\x100",
  		"\\xG"])
      end;
  end
  