diff options
-rw-r--r-- | .travis.yml | 7 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | include/urweb/types_cpp.h | 3 | ||||
-rw-r--r-- | include/urweb/urweb_cpp.h | 5 | ||||
-rw-r--r-- | lib/js/urweb.js | 2994 | ||||
-rw-r--r-- | lib/ur/basis.urs | 3 | ||||
-rw-r--r-- | src/c/Makefile.am | 4 | ||||
-rw-r--r-- | src/c/urweb.c | 452 | ||||
-rw-r--r-- | src/compiler.sml | 5 | ||||
-rw-r--r-- | src/config.sig | 3 | ||||
-rw-r--r-- | src/config.sml.in | 3 | ||||
-rw-r--r-- | src/settings.sig | 2 | ||||
-rw-r--r-- | src/settings.sml | 3 | ||||
-rw-r--r-- | tests/Makefile | 2 | ||||
-rw-r--r-- | tests/utf8.py | 174 | ||||
-rw-r--r-- | tests/utf8.ur | 794 | ||||
-rw-r--r-- | tests/utf8.urp | 6 |
17 files changed, 4229 insertions, 233 deletions
diff --git a/.travis.yml b/.travis.yml index df4e4abc..1f768f6d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,11 +18,14 @@ compiler: before_install: - export CONFIGURE_ARGS="" - if command -v apt-get &>/dev/null; then sudo apt-get update -qq; fi - - if command -v apt-get &>/dev/null; then sudo apt-get install -y mlton; fi + - if command -v apt-get &>/dev/null; then sudo apt-get install -y mlton libicu-dev; fi - if command -v brew &>/dev/null; then brew update; fi - if command -v brew &>/dev/null; then brew uninstall libtool; fi - if command -v brew &>/dev/null; then brew install libtool; fi - - if command -v brew &>/dev/null; then brew install openssl mlton; fi + - if command -v brew &>/dev/null; then brew install openssl mlton icu4c; fi + - if command -v brew &>/dev/null; then export ICU_INCLUDES=-I"`brew --prefix icu4c`/include"; fi + - if command -v brew &>/dev/null; then export ICU_LIBS=-L"`brew --prefix icu4c`/lib"; fi - if command -v brew &>/dev/null; then export CONFIGURE_ARGS="--with-openssl=/usr/local/opt/openssl"; fi + script: ./autogen.sh && ./configure $CONFIGURE_ARGS && make && make test diff --git a/configure.ac b/configure.ac index 75bba230..696aac84 100644 --- a/configure.ac +++ b/configure.ac @@ -127,6 +127,8 @@ AC_SUBST(SQHEADER) AC_SUBST(VERSION) AC_SUBST(PTHREAD_CFLAGS) AC_SUBST(PTHREAD_LIBS) +AC_SUBST(ICU_INCLUDES) +AC_SUBST(ICU_LIBS) AC_CONFIG_FILES([ Makefile diff --git a/include/urweb/types_cpp.h b/include/urweb/types_cpp.h index 0c546d1c..c6c0dd3e 100644 --- a/include/urweb/types_cpp.h +++ b/include/urweb/types_cpp.h @@ -4,11 +4,12 @@ #include <time.h> #include <unistd.h> #include <stdint.h> +#include <unicode/utypes.h> typedef long long uw_Basis_int; typedef double uw_Basis_float; typedef char* uw_Basis_string; -typedef char uw_Basis_char; +typedef UChar32 uw_Basis_char; typedef struct { time_t seconds; unsigned microseconds; diff --git a/include/urweb/urweb_cpp.h b/include/urweb/urweb_cpp.h index 5f1144b8..25f97fb3 100644 --- a/include/urweb/urweb_cpp.h +++ b/include/urweb/urweb_cpp.h @@ -103,7 +103,7 @@ char *uw_Basis_htmlifyFloat(struct uw_context *, uw_Basis_float); char *uw_Basis_htmlifyString(struct uw_context *, uw_Basis_string); char *uw_Basis_htmlifyBool(struct uw_context *, uw_Basis_bool); char *uw_Basis_htmlifyTime(struct uw_context *, uw_Basis_time); -char *uw_Basis_htmlifySpecialChar(struct uw_context *, unsigned char); +char *uw_Basis_htmlifySpecialChar(struct uw_context *, uw_Basis_char); char *uw_Basis_htmlifySource(struct uw_context *, uw_Basis_source); uw_unit uw_Basis_htmlifyInt_w(struct uw_context *, uw_Basis_int); @@ -111,7 +111,7 @@ uw_unit uw_Basis_htmlifyFloat_w(struct uw_context *, uw_Basis_float); uw_unit uw_Basis_htmlifyString_w(struct uw_context *, uw_Basis_string); uw_unit uw_Basis_htmlifyBool_w(struct uw_context *, uw_Basis_bool); uw_unit uw_Basis_htmlifyTime_w(struct uw_context *, uw_Basis_time); -uw_unit uw_Basis_htmlifySpecialChar_w(struct uw_context *, unsigned char); +uw_unit uw_Basis_htmlifySpecialChar_w(struct uw_context *, uw_Basis_char); uw_unit uw_Basis_htmlifySource_w(struct uw_context *, uw_Basis_source); char *uw_Basis_attrifyInt(struct uw_context *, uw_Basis_int); @@ -327,6 +327,7 @@ uw_Basis_bool uw_Basis_isxdigit(struct uw_context *, uw_Basis_char); uw_Basis_char uw_Basis_tolower(struct uw_context *, uw_Basis_char); uw_Basis_char uw_Basis_toupper(struct uw_context *, uw_Basis_char); +uw_Basis_bool uw_Basis_iscodepoint(struct uw_context *, uw_Basis_int); uw_Basis_int uw_Basis_ord(struct uw_context *, uw_Basis_char); uw_Basis_char uw_Basis_chr(struct uw_context *, uw_Basis_int); diff --git a/lib/js/urweb.js b/lib/js/urweb.js index f81f05e3..2d39bc69 100644 --- a/lib/js/urweb.js +++ b/lib/js/urweb.js @@ -27,18 +27,2882 @@ function le(x, y) { return x <= y; } // Characters -function isLower(c) { return c >= 'a' && c <= 'z'; } -function isUpper(c) { return c >= 'A' && c <= 'Z'; } -function isAlpha(c) { return isLower(c) || isUpper(c); } -function isDigit(c) { return c >= '0' && c <= '9'; } +function ord(c) { return c.codePointAt(0); } + +function isLower(c) { + var cp = ord(c); + + if (cp >= 97 && cp <= 122) return true; + if (cp == 170) return true; + if (cp == 181) return true; + if (cp == 186) return true; + if (cp >= 223 && cp <= 246) return true; + if (cp >= 248 && cp <= 255) return true; + if (cp == 257) return true; + if (cp == 259) return true; + if (cp == 261) return true; + if (cp == 263) return true; + if (cp == 265) return true; + if (cp == 267) return true; + if (cp == 269) return true; + if (cp == 271) return true; + if (cp == 273) return true; + if (cp == 275) return true; + if (cp == 277) return true; + if (cp == 279) return true; + if (cp == 281) return true; + if (cp == 283) return true; + if (cp == 285) return true; + if (cp == 287) return true; + if (cp == 289) return true; + if (cp == 291) return true; + if (cp == 293) return true; + if (cp == 295) return true; + if (cp == 297) return true; + if (cp == 299) return true; + if (cp == 301) return true; + if (cp == 303) return true; + if (cp == 305) return true; + if (cp == 307) return true; + if (cp == 309) return true; + if (cp >= 311 && cp <= 312) return true; + if (cp == 314) return true; + if (cp == 316) return true; + if (cp == 318) return true; + if (cp == 320) return true; + if (cp == 322) return true; + if (cp == 324) return true; + if (cp == 326) return true; + if (cp >= 328 && cp <= 329) return true; + if (cp == 331) return true; + if (cp == 333) return true; + if (cp == 335) return true; + if (cp == 337) return true; + if (cp == 339) return true; + if (cp == 341) return true; + if (cp == 343) return true; + if (cp == 345) return true; + if (cp == 347) return true; + if (cp == 349) return true; + if (cp == 351) return true; + if (cp == 353) return true; + if (cp == 355) return true; + if (cp == 357) return true; + if (cp == 359) return true; + if (cp == 361) return true; + if (cp == 363) return true; + if (cp == 365) return true; + if (cp == 367) return true; + if (cp == 369) return true; + if (cp == 371) return true; + if (cp == 373) return true; + if (cp == 375) return true; + if (cp == 378) return true; + if (cp == 380) return true; + if (cp >= 382 && cp <= 384) return true; + if (cp == 387) return true; + if (cp == 389) return true; + if (cp == 392) return true; + if (cp >= 396 && cp <= 397) return true; + if (cp == 402) return true; + if (cp == 405) return true; + if (cp >= 409 && cp <= 411) return true; + if (cp == 414) return true; + if (cp == 417) return true; + if (cp == 419) return true; + if (cp == 421) return true; + if (cp == 424) return true; + if (cp >= 426 && cp <= 427) return true; + if (cp == 429) return true; + if (cp == 432) return true; + if (cp == 436) return true; + if (cp == 438) return true; + if (cp >= 441 && cp <= 442) return true; + if (cp >= 445 && cp <= 447) return true; + if (cp == 454) return true; + if (cp == 457) return true; + if (cp == 460) return true; + if (cp == 462) return true; + if (cp == 464) return true; + if (cp == 466) return true; + if (cp == 468) return true; + if (cp == 470) return true; + if (cp == 472) return true; + if (cp == 474) return true; + if (cp >= 476 && cp <= 477) return true; + if (cp == 479) return true; + if (cp == 481) return true; + if (cp == 483) return true; + if (cp == 485) return true; + if (cp == 487) return true; + if (cp == 489) return true; + if (cp == 491) return true; + if (cp == 493) return true; + if (cp >= 495 && cp <= 496) return true; + if (cp == 499) return true; + if (cp == 501) return true; + if (cp == 505) return true; + if (cp == 507) return true; + if (cp == 509) return true; + if (cp == 511) return true; + if (cp == 513) return true; + if (cp == 515) return true; + if (cp == 517) return true; + if (cp == 519) return true; + if (cp == 521) return true; + if (cp == 523) return true; + if (cp == 525) return true; + if (cp == 527) return true; + if (cp == 529) return true; + if (cp == 531) return true; + if (cp == 533) return true; + if (cp == 535) return true; + if (cp == 537) return true; + if (cp == 539) return true; + if (cp == 541) return true; + if (cp == 543) return true; + if (cp == 545) return true; + if (cp == 547) return true; + if (cp == 549) return true; + if (cp == 551) return true; + if (cp == 553) return true; + if (cp == 555) return true; + if (cp == 557) return true; + if (cp == 559) return true; + if (cp == 561) return true; + if (cp >= 563 && cp <= 569) return true; + if (cp == 572) return true; + if (cp >= 575 && cp <= 576) return true; + if (cp == 578) return true; + if (cp == 583) return true; + if (cp == 585) return true; + if (cp == 587) return true; + if (cp == 589) return true; + if (cp >= 591 && cp <= 659) return true; + if (cp >= 661 && cp <= 696) return true; + if (cp >= 704 && cp <= 705) return true; + if (cp >= 736 && cp <= 740) return true; + if (cp == 837) return true; + if (cp == 881) return true; + if (cp == 883) return true; + if (cp == 887) return true; + if (cp >= 890 && cp <= 893) return true; + if (cp == 912) return true; + if (cp >= 940 && cp <= 974) return true; + if (cp >= 976 && cp <= 977) return true; + if (cp >= 981 && cp <= 983) return true; + if (cp == 985) return true; + if (cp == 987) return true; + if (cp == 989) return true; + if (cp == 991) return true; + if (cp == 993) return true; + if (cp == 995) return true; + if (cp == 997) return true; + if (cp == 999) return true; + if (cp == 1001) return true; + if (cp == 1003) return true; + if (cp == 1005) return true; + if (cp >= 1007 && cp <= 1011) return true; + if (cp == 1013) return true; + if (cp == 1016) return true; + if (cp >= 1019 && cp <= 1020) return true; + if (cp >= 1072 && cp <= 1119) return true; + if (cp == 1121) return true; + if (cp == 1123) return true; + if (cp == 1125) return true; + if (cp == 1127) return true; + if (cp == 1129) return true; + if (cp == 1131) return true; + if (cp == 1133) return true; + if (cp == 1135) return true; + if (cp == 1137) return true; + if (cp == 1139) return true; + if (cp == 1141) return true; + if (cp == 1143) return true; + if (cp == 1145) return true; + if (cp == 1147) return true; + if (cp == 1149) return true; + if (cp == 1151) return true; + if (cp == 1153) return true; + if (cp == 1163) return true; + if (cp == 1165) return true; + if (cp == 1167) return true; + if (cp == 1169) return true; + if (cp == 1171) return true; + if (cp == 1173) return true; + if (cp == 1175) return true; + if (cp == 1177) return true; + if (cp == 1179) return true; + if (cp == 1181) return true; + if (cp == 1183) return true; + if (cp == 1185) return true; + if (cp == 1187) return true; + if (cp == 1189) return true; + if (cp == 1191) return true; + if (cp == 1193) return true; + if (cp == 1195) return true; + if (cp == 1197) return true; + if (cp == 1199) return true; + if (cp == 1201) return true; + if (cp == 1203) return true; + if (cp == 1205) return true; + if (cp == 1207) return true; + if (cp == 1209) return true; + if (cp == 1211) return true; + if (cp == 1213) return true; + if (cp == 1215) return true; + if (cp == 1218) return true; + if (cp == 1220) return true; + if (cp == 1222) return true; + if (cp == 1224) return true; + if (cp == 1226) return true; + if (cp == 1228) return true; + if (cp >= 1230 && cp <= 1231) return true; + if (cp == 1233) return true; + if (cp == 1235) return true; + if (cp == 1237) return true; + if (cp == 1239) return true; + if (cp == 1241) return true; + if (cp == 1243) return true; + if (cp == 1245) return true; + if (cp == 1247) return true; + if (cp == 1249) return true; + if (cp == 1251) return true; + if (cp == 1253) return true; + if (cp == 1255) return true; + if (cp == 1257) return true; + if (cp == 1259) return true; + if (cp == 1261) return true; + if (cp == 1263) return true; + if (cp == 1265) return true; + if (cp == 1267) return true; + if (cp == 1269) return true; + if (cp == 1271) return true; + if (cp == 1273) return true; + if (cp == 1275) return true; + if (cp == 1277) return true; + if (cp == 1279) return true; + if (cp == 1281) return true; + if (cp == 1283) return true; + if (cp == 1285) return true; + if (cp == 1287) return true; + if (cp == 1289) return true; + if (cp == 1291) return true; + if (cp == 1293) return true; + if (cp == 1295) return true; + if (cp == 1297) return true; + if (cp == 1299) return true; + if (cp == 1301) return true; + if (cp == 1303) return true; + if (cp == 1305) return true; + if (cp == 1307) return true; + if (cp == 1309) return true; + if (cp == 1311) return true; + if (cp == 1313) return true; + if (cp == 1315) return true; + if (cp == 1317) return true; + if (cp == 1319) return true; + if (cp == 1321) return true; + if (cp == 1323) return true; + if (cp == 1325) return true; + if (cp == 1327) return true; + if (cp >= 1377 && cp <= 1415) return true; + if (cp >= 5112 && cp <= 5117) return true; + if (cp >= 7296 && cp <= 7304) return true; + if (cp >= 7424 && cp <= 7615) return true; + if (cp == 7681) return true; + if (cp == 7683) return true; + if (cp == 7685) return true; + if (cp == 7687) return true; + if (cp == 7689) return true; + if (cp == 7691) return true; + if (cp == 7693) return true; + if (cp == 7695) return true; + if (cp == 7697) return true; + if (cp == 7699) return true; + if (cp == 7701) return true; + if (cp == 7703) return true; + if (cp == 7705) return true; + if (cp == 7707) return true; + if (cp == 7709) return true; + if (cp == 7711) return true; + if (cp == 7713) return true; + if (cp == 7715) return true; + if (cp == 7717) return true; + if (cp == 7719) return true; + if (cp == 7721) return true; + if (cp == 7723) return true; + if (cp == 7725) return true; + if (cp == 7727) return true; + if (cp == 7729) return true; + if (cp == 7731) return true; + if (cp == 7733) return true; + if (cp == 7735) return true; + if (cp == 7737) return true; + if (cp == 7739) return true; + if (cp == 7741) return true; + if (cp == 7743) return true; + if (cp == 7745) return true; + if (cp == 7747) return true; + if (cp == 7749) return true; + if (cp == 7751) return true; + if (cp == 7753) return true; + if (cp == 7755) return true; + if (cp == 7757) return true; + if (cp == 7759) return true; + if (cp == 7761) return true; + if (cp == 7763) return true; + if (cp == 7765) return true; + if (cp == 7767) return true; + if (cp == 7769) return true; + if (cp == 7771) return true; + if (cp == 7773) return true; + if (cp == 7775) return true; + if (cp == 7777) return true; + if (cp == 7779) return true; + if (cp == 7781) return true; + if (cp == 7783) return true; + if (cp == 7785) return true; + if (cp == 7787) return true; + if (cp == 7789) return true; + if (cp == 7791) return true; + if (cp == 7793) return true; + if (cp == 7795) return true; + if (cp == 7797) return true; + if (cp == 7799) return true; + if (cp == 7801) return true; + if (cp == 7803) return true; + if (cp == 7805) return true; + if (cp == 7807) return true; + if (cp == 7809) return true; + if (cp == 7811) return true; + if (cp == 7813) return true; + if (cp == 7815) return true; + if (cp == 7817) return true; + if (cp == 7819) return true; + if (cp == 7821) return true; + if (cp == 7823) return true; + if (cp == 7825) return true; + if (cp == 7827) return true; + if (cp >= 7829 && cp <= 7837) return true; + if (cp == 7839) return true; + if (cp == 7841) return true; + if (cp == 7843) return true; + if (cp == 7845) return true; + if (cp == 7847) return true; + if (cp == 7849) return true; + if (cp == 7851) return true; + if (cp == 7853) return true; + if (cp == 7855) return true; + if (cp == 7857) return true; + if (cp == 7859) return true; + if (cp == 7861) return true; + if (cp == 7863) return true; + if (cp == 7865) return true; + if (cp == 7867) return true; + if (cp == 7869) return true; + if (cp == 7871) return true; + if (cp == 7873) return true; + if (cp == 7875) return true; + if (cp == 7877) return true; + if (cp == 7879) return true; + if (cp == 7881) return true; + if (cp == 7883) return true; + if (cp == 7885) return true; + if (cp == 7887) return true; + if (cp == 7889) return true; + if (cp == 7891) return true; + if (cp == 7893) return true; + if (cp == 7895) return true; + if (cp == 7897) return true; + if (cp == 7899) return true; + if (cp == 7901) return true; + if (cp == 7903) return true; + if (cp == 7905) return true; + if (cp == 7907) return true; + if (cp == 7909) return true; + if (cp == 7911) return true; + if (cp == 7913) return true; + if (cp == 7915) return true; + if (cp == 7917) return true; + if (cp == 7919) return true; + if (cp == 7921) return true; + if (cp == 7923) return true; + if (cp == 7925) return true; + if (cp == 7927) return true; + if (cp == 7929) return true; + if (cp == 7931) return true; + if (cp == 7933) return true; + if (cp >= 7935 && cp <= 7943) return true; + if (cp >= 7952 && cp <= 7957) return true; + if (cp >= 7968 && cp <= 7975) return true; + if (cp >= 7984 && cp <= 7991) return true; + if (cp >= 8000 && cp <= 8005) return true; + if (cp >= 8016 && cp <= 8023) return true; + if (cp >= 8032 && cp <= 8039) return true; + if (cp >= 8048 && cp <= 8061) return true; + if (cp >= 8064 && cp <= 8071) return true; + if (cp >= 8080 && cp <= 8087) return true; + if (cp >= 8096 && cp <= 8103) return true; + if (cp >= 8112 && cp <= 8116) return true; + if (cp >= 8118 && cp <= 8119) return true; + if (cp == 8126) return true; + if (cp >= 8130 && cp <= 8132) return true; + if (cp >= 8134 && cp <= 8135) return true; + if (cp >= 8144 && cp <= 8147) return true; + if (cp >= 8150 && cp <= 8151) return true; + if (cp >= 8160 && cp <= 8167) return true; + if (cp >= 8178 && cp <= 8180) return true; + if (cp >= 8182 && cp <= 8183) return true; + if (cp == 8305) return true; + if (cp == 8319) return true; + if (cp >= 8336 && cp <= 8348) return true; + if (cp == 8458) return true; + if (cp >= 8462 && cp <= 8463) return true; + if (cp == 8467) return true; + if (cp == 8495) return true; + if (cp == 8500) return true; + if (cp == 8505) return true; + if (cp >= 8508 && cp <= 8509) return true; + if (cp >= 8518 && cp <= 8521) return true; + if (cp == 8526) return true; + if (cp >= 8560 && cp <= 8575) return true; + if (cp == 8580) return true; + if (cp >= 9424 && cp <= 9449) return true; + if (cp >= 11312 && cp <= 11358) return true; + if (cp == 11361) return true; + if (cp >= 11365 && cp <= 11366) return true; + if (cp == 11368) return true; + if (cp == 11370) return true; + if (cp == 11372) return true; + if (cp == 11377) return true; + if (cp >= 11379 && cp <= 11380) return true; + if (cp >= 11382 && cp <= 11389) return true; + if (cp == 11393) return true; + if (cp == 11395) return true; + if (cp == 11397) return true; + if (cp == 11399) return true; + if (cp == 11401) return true; + if (cp == 11403) return true; + if (cp == 11405) return true; + if (cp == 11407) return true; + if (cp == 11409) return true; + if (cp == 11411) return true; + if (cp == 11413) return true; + if (cp == 11415) return true; + if (cp == 11417) return true; + if (cp == 11419) return true; + if (cp == 11421) return true; + if (cp == 11423) return true; + if (cp == 11425) return true; + if (cp == 11427) return true; + if (cp == 11429) return true; + if (cp == 11431) return true; + if (cp == 11433) return true; + if (cp == 11435) return true; + if (cp == 11437) return true; + if (cp == 11439) return true; + if (cp == 11441) return true; + if (cp == 11443) return true; + if (cp == 11445) return true; + if (cp == 11447) return true; + if (cp == 11449) return true; + if (cp == 11451) return true; + if (cp == 11453) return true; + if (cp == 11455) return true; + if (cp == 11457) return true; + if (cp == 11459) return true; + if (cp == 11461) return true; + if (cp == 11463) return true; + if (cp == 11465) return true; + if (cp == 11467) return true; + if (cp == 11469) return true; + if (cp == 11471) return true; + if (cp == 11473) return true; + if (cp == 11475) return true; + if (cp == 11477) return true; + if (cp == 11479) return true; + if (cp == 11481) return true; + if (cp == 11483) return true; + if (cp == 11485) return true; + if (cp == 11487) return true; + if (cp == 11489) return true; + if (cp >= 11491 && cp <= 11492) return true; + if (cp == 11500) return true; + if (cp == 11502) return true; + if (cp == 11507) return true; + if (cp >= 11520 && cp <= 11557) return true; + if (cp == 11559) return true; + if (cp == 11565) return true; + if (cp == 42561) return true; + if (cp == 42563) return true; + if (cp == 42565) return true; + if (cp == 42567) return true; + if (cp == 42569) return true; + if (cp == 42571) return true; + if (cp == 42573) return true; + if (cp == 42575) return true; + if (cp == 42577) return true; + if (cp == 42579) return true; + if (cp == 42581) return true; + if (cp == 42583) return true; + if (cp == 42585) return true; + if (cp == 42587) return true; + if (cp == 42589) return true; + if (cp == 42591) return true; + if (cp == 42593) return true; + if (cp == 42595) return true; + if (cp == 42597) return true; + if (cp == 42599) return true; + if (cp == 42601) return true; + if (cp == 42603) return true; + if (cp == 42605) return true; + if (cp == 42625) return true; + if (cp == 42627) return true; + if (cp == 42629) return true; + if (cp == 42631) return true; + if (cp == 42633) return true; + if (cp == 42635) return true; + if (cp == 42637) return true; + if (cp == 42639) return true; + if (cp == 42641) return true; + if (cp == 42643) return true; + if (cp == 42645) return true; + if (cp == 42647) return true; + if (cp == 42649) return true; + if (cp >= 42651 && cp <= 42653) return true; + if (cp == 42787) return true; + if (cp == 42789) return true; + if (cp == 42791) return true; + if (cp == 42793) return true; + if (cp == 42795) return true; + if (cp == 42797) return true; + if (cp >= 42799 && cp <= 42801) return true; + if (cp == 42803) return true; + if (cp == 42805) return true; + if (cp == 42807) return true; + if (cp == 42809) return true; + if (cp == 42811) return true; + if (cp == 42813) return true; + if (cp == 42815) return true; + if (cp == 42817) return true; + if (cp == 42819) return true; + if (cp == 42821) return true; + if (cp == 42823) return true; + if (cp == 42825) return true; + if (cp == 42827) return true; + if (cp == 42829) return true; + if (cp == 42831) return true; + if (cp == 42833) return true; + if (cp == 42835) return true; + if (cp == 42837) return true; + if (cp == 42839) return true; + if (cp == 42841) return true; + if (cp == 42843) return true; + if (cp == 42845) return true; + if (cp == 42847) return true; + if (cp == 42849) return true; + if (cp == 42851) return true; + if (cp == 42853) return true; + if (cp == 42855) return true; + if (cp == 42857) return true; + if (cp == 42859) return true; + if (cp == 42861) return true; + if (cp >= 42863 && cp <= 42872) return true; + if (cp == 42874) return true; + if (cp == 42876) return true; + if (cp == 42879) return true; + if (cp == 42881) return true; + if (cp == 42883) return true; + if (cp == 42885) return true; + if (cp == 42887) return true; + if (cp == 42892) return true; + if (cp == 42894) return true; + if (cp == 42897) return true; + if (cp >= 42899 && cp <= 42901) return true; + if (cp == 42903) return true; + if (cp == 42905) return true; + if (cp == 42907) return true; + if (cp == 42909) return true; + if (cp == 42911) return true; + if (cp == 42913) return true; + if (cp == 42915) return true; + if (cp == 42917) return true; + if (cp == 42919) return true; + if (cp == 42921) return true; + if (cp == 42933) return true; + if (cp == 42935) return true; + if (cp >= 43000 && cp <= 43002) return true; + if (cp >= 43824 && cp <= 43866) return true; + if (cp >= 43868 && cp <= 43877) return true; + if (cp >= 43888 && cp <= 43967) return true; + if (cp >= 64256 && cp <= 64262) return true; + if (cp >= 64275 && cp <= 64279) return true; + if (cp >= 65345 && cp <= 65370) return true; + if (cp >= 66600 && cp <= 66639) return true; + if (cp >= 66776 && cp <= 66811) return true; + if (cp >= 68800 && cp <= 68850) return true; + if (cp >= 71872 && cp <= 71903) return true; + if (cp >= 119834 && cp <= 119859) return true; + if (cp >= 119886 && cp <= 119892) return true; + if (cp >= 119894 && cp <= 119911) return true; + if (cp >= 119938 && cp <= 119963) return true; + if (cp >= 119990 && cp <= 119993) return true; + if (cp == 119995) return true; + if (cp >= 119997 && cp <= 120003) return true; + if (cp >= 120005 && cp <= 120015) return true; + if (cp >= 120042 && cp <= 120067) return true; + if (cp >= 120094 && cp <= 120119) return true; + if (cp >= 120146 && cp <= 120171) return true; + if (cp >= 120198 && cp <= 120223) return true; + if (cp >= 120250 && cp <= 120275) return true; + if (cp >= 120302 && cp <= 120327) return true; + if (cp >= 120354 && cp <= 120379) return true; + if (cp >= 120406 && cp <= 120431) return true; + if (cp >= 120458 && cp <= 120485) return true; + if (cp >= 120514 && cp <= 120538) return true; + if (cp >= 120540 && cp <= 120545) return true; + if (cp >= 120572 && cp <= 120596) return true; + if (cp >= 120598 && cp <= 120603) return true; + if (cp >= 120630 && cp <= 120654) return true; + if (cp >= 120656 && cp <= 120661) return true; + if (cp >= 120688 && cp <= 120712) return true; + if (cp >= 120714 && cp <= 120719) return true; + if (cp >= 120746 && cp <= 120770) return true; + if (cp >= 120772 && cp <= 120777) return true; + if (cp == 120779) return true; + if (cp >= 125218 && cp <= 125251) return true; + + return false; +} + +function isUpper(c) { + var cp = ord(c); + + if (cp >= 65 && cp <= 90) return true; + if (cp >= 192 && cp <= 214) return true; + if (cp >= 216 && cp <= 222) return true; + if (cp == 256) return true; + if (cp == 258) return true; + if (cp == 260) return true; + if (cp == 262) return true; + if (cp == 264) return true; + if (cp == 266) return true; + if (cp == 268) return true; + if (cp == 270) return true; + if (cp == 272) return true; + if (cp == 274) return true; + if (cp == 276) return true; + if (cp == 278) return true; + if (cp == 280) return true; + if (cp == 282) return true; + if (cp == 284) return true; + if (cp == 286) return true; + if (cp == 288) return true; + if (cp == 290) return true; + if (cp == 292) return true; + if (cp == 294) return true; + if (cp == 296) return true; + if (cp == 298) return true; + if (cp == 300) return true; + if (cp == 302) return true; + if (cp == 304) return true; + if (cp == 306) return true; + if (cp == 308) return true; + if (cp == 310) return true; + if (cp == 313) return true; + if (cp == 315) return true; + if (cp == 317) return true; + if (cp == 319) return true; + if (cp == 321) return true; + if (cp == 323) return true; + if (cp == 325) return true; + if (cp == 327) return true; + if (cp == 330) return true; + if (cp == 332) return true; + if (cp == 334) return true; + if (cp == 336) return true; + if (cp == 338) return true; + if (cp == 340) return true; + if (cp == 342) return true; + if (cp == 344) return true; + if (cp == 346) return true; + if (cp == 348) return true; + if (cp == 350) return true; + if (cp == 352) return true; + if (cp == 354) return true; + if (cp == 356) return true; + if (cp == 358) return true; + if (cp == 360) return true; + if (cp == 362) return true; + if (cp == 364) return true; + if (cp == 366) return true; + if (cp == 368) return true; + if (cp == 370) return true; + if (cp == 372) return true; + if (cp == 374) return true; + if (cp >= 376 && cp <= 377) return true; + if (cp == 379) return true; + if (cp == 381) return true; + if (cp >= 385 && cp <= 386) return true; + if (cp == 388) return true; + if (cp >= 390 && cp <= 391) return true; + if (cp >= 393 && cp <= 395) return true; + if (cp >= 398 && cp <= 401) return true; + if (cp >= 403 && cp <= 404) return true; + if (cp >= 406 && cp <= 408) return true; + if (cp >= 412 && cp <= 413) return true; + if (cp >= 415 && cp <= 416) return true; + if (cp == 418) return true; + if (cp == 420) return true; + if (cp >= 422 && cp <= 423) return true; + if (cp == 425) return true; + if (cp == 428) return true; + if (cp >= 430 && cp <= 431) return true; + if (cp >= 433 && cp <= 435) return true; + if (cp == 437) return true; + if (cp >= 439 && cp <= 440) return true; + if (cp == 444) return true; + if (cp == 452) return true; + if (cp == 455) return true; + if (cp == 458) return true; + if (cp == 461) return true; + if (cp == 463) return true; + if (cp == 465) return true; + if (cp == 467) return true; + if (cp == 469) return true; + if (cp == 471) return true; + if (cp == 473) return true; + if (cp == 475) return true; + if (cp == 478) return true; + if (cp == 480) return true; + if (cp == 482) return true; + if (cp == 484) return true; + if (cp == 486) return true; + if (cp == 488) return true; + if (cp == 490) return true; + if (cp == 492) return true; + if (cp == 494) return true; + if (cp == 497) return true; + if (cp == 500) return true; + if (cp >= 502 && cp <= 504) return true; + if (cp == 506) return true; + if (cp == 508) return true; + if (cp == 510) return true; + if (cp == 512) return true; + if (cp == 514) return true; + if (cp == 516) return true; + if (cp == 518) return true; + if (cp == 520) return true; + if (cp == 522) return true; + if (cp == 524) return true; + if (cp == 526) return true; + if (cp == 528) return true; + if (cp == 530) return true; + if (cp == 532) return true; + if (cp == 534) return true; + if (cp == 536) return true; + if (cp == 538) return true; + if (cp == 540) return true; + if (cp == 542) return true; + if (cp == 544) return true; + if (cp == 546) return true; + if (cp == 548) return true; + if (cp == 550) return true; + if (cp == 552) return true; + if (cp == 554) return true; + if (cp == 556) return true; + if (cp == 558) return true; + if (cp == 560) return true; + if (cp == 562) return true; + if (cp >= 570 && cp <= 571) return true; + if (cp >= 573 && cp <= 574) return true; + if (cp == 577) return true; + if (cp >= 579 && cp <= 582) return true; + if (cp == 584) return true; + if (cp == 586) return true; + if (cp == 588) return true; + if (cp == 590) return true; + if (cp == 880) return true; + if (cp == 882) return true; + if (cp == 886) return true; + if (cp == 895) return true; + if (cp == 902) return true; + if (cp >= 904 && cp <= 906) return true; + if (cp == 908) return true; + if (cp >= 910 && cp <= 911) return true; + if (cp >= 913 && cp <= 929) return true; + if (cp >= 931 && cp <= 939) return true; + if (cp == 975) return true; + if (cp >= 978 && cp <= 980) return true; + if (cp == 984) return true; + if (cp == 986) return true; + if (cp == 988) return true; + if (cp == 990) return true; + if (cp == 992) return true; + if (cp == 994) return true; + if (cp == 996) return true; + if (cp == 998) return true; + if (cp == 1000) return true; + if (cp == 1002) return true; + if (cp == 1004) return true; + if (cp == 1006) return true; + if (cp == 1012) return true; + if (cp == 1015) return true; + if (cp >= 1017 && cp <= 1018) return true; + if (cp >= 1021 && cp <= 1071) return true; + if (cp == 1120) return true; + if (cp == 1122) return true; + if (cp == 1124) return true; + if (cp == 1126) return true; + if (cp == 1128) return true; + if (cp == 1130) return true; + if (cp == 1132) return true; + if (cp == 1134) return true; + if (cp == 1136) return true; + if (cp == 1138) return true; + if (cp == 1140) return true; + if (cp == 1142) return true; + if (cp == 1144) return true; + if (cp == 1146) return true; + if (cp == 1148) return true; + if (cp == 1150) return true; + if (cp == 1152) return true; + if (cp == 1162) return true; + if (cp == 1164) return true; + if (cp == 1166) return true; + if (cp == 1168) return true; + if (cp == 1170) return true; + if (cp == 1172) return true; + if (cp == 1174) return true; + if (cp == 1176) return true; + if (cp == 1178) return true; + if (cp == 1180) return true; + if (cp == 1182) return true; + if (cp == 1184) return true; + if (cp == 1186) return true; + if (cp == 1188) return true; + if (cp == 1190) return true; + if (cp == 1192) return true; + if (cp == 1194) return true; + if (cp == 1196) return true; + if (cp == 1198) return true; + if (cp == 1200) return true; + if (cp == 1202) return true; + if (cp == 1204) return true; + if (cp == 1206) return true; + if (cp == 1208) return true; + if (cp == 1210) return true; + if (cp == 1212) return true; + if (cp == 1214) return true; + if (cp >= 1216 && cp <= 1217) return true; + if (cp == 1219) return true; + if (cp == 1221) return true; + if (cp == 1223) return true; + if (cp == 1225) return true; + if (cp == 1227) return true; + if (cp == 1229) return true; + if (cp == 1232) return true; + if (cp == 1234) return true; + if (cp == 1236) return true; + if (cp == 1238) return true; + if (cp == 1240) return true; + if (cp == 1242) return true; + if (cp == 1244) return true; + if (cp == 1246) return true; + if (cp == 1248) return true; + if (cp == 1250) return true; + if (cp == 1252) return true; + if (cp == 1254) return true; + if (cp == 1256) return true; + if (cp == 1258) return true; + if (cp == 1260) return true; + if (cp == 1262) return true; + if (cp == 1264) return true; + if (cp == 1266) return true; + if (cp == 1268) return true; + if (cp == 1270) return true; + if (cp == 1272) return true; + if (cp == 1274) return true; + if (cp == 1276) return true; + if (cp == 1278) return true; + if (cp == 1280) return true; + if (cp == 1282) return true; + if (cp == 1284) return true; + if (cp == 1286) return true; + if (cp == 1288) return true; + if (cp == 1290) return true; + if (cp == 1292) return true; + if (cp == 1294) return true; + if (cp == 1296) return true; + if (cp == 1298) return true; + if (cp == 1300) return true; + if (cp == 1302) return true; + if (cp == 1304) return true; + if (cp == 1306) return true; + if (cp == 1308) return true; + if (cp == 1310) return true; + if (cp == 1312) return true; + if (cp == 1314) return true; + if (cp == 1316) return true; + if (cp == 1318) return true; + if (cp == 1320) return true; + if (cp == 1322) return true; + if (cp == 1324) return true; + if (cp == 1326) return true; + if (cp >= 1329 && cp <= 1366) return true; + if (cp >= 4256 && cp <= 4293) return true; + if (cp == 4295) return true; + if (cp == 4301) return true; + if (cp >= 5024 && cp <= 5109) return true; + if (cp == 7680) return true; + if (cp == 7682) return true; + if (cp == 7684) return true; + if (cp == 7686) return true; + if (cp == 7688) return true; + if (cp == 7690) return true; + if (cp == 7692) return true; + if (cp == 7694) return true; + if (cp == 7696) return true; + if (cp == 7698) return true; + if (cp == 7700) return true; + if (cp == 7702) return true; + if (cp == 7704) return true; + if (cp == 7706) return true; + if (cp == 7708) return true; + if (cp == 7710) return true; + if (cp == 7712) return true; + if (cp == 7714) return true; + if (cp == 7716) return true; + if (cp == 7718) return true; + if (cp == 7720) return true; + if (cp == 7722) return true; + if (cp == 7724) return true; + if (cp == 7726) return true; + if (cp == 7728) return true; + if (cp == 7730) return true; + if (cp == 7732) return true; + if (cp == 7734) return true; + if (cp == 7736) return true; + if (cp == 7738) return true; + if (cp == 7740) return true; + if (cp == 7742) return true; + if (cp == 7744) return true; + if (cp == 7746) return true; + if (cp == 7748) return true; + if (cp == 7750) return true; + if (cp == 7752) return true; + if (cp == 7754) return true; + if (cp == 7756) return true; + if (cp == 7758) return true; + if (cp == 7760) return true; + if (cp == 7762) return true; + if (cp == 7764) return true; + if (cp == 7766) return true; + if (cp == 7768) return true; + if (cp == 7770) return true; + if (cp == 7772) return true; + if (cp == 7774) return true; + if (cp == 7776) return true; + if (cp == 7778) return true; + if (cp == 7780) return true; + if (cp == 7782) return true; + if (cp == 7784) return true; + if (cp == 7786) return true; + if (cp == 7788) return true; + if (cp == 7790) return true; + if (cp == 7792) return true; + if (cp == 7794) return true; + if (cp == 7796) return true; + if (cp == 7798) return true; + if (cp == 7800) return true; + if (cp == 7802) return true; + if (cp == 7804) return true; + if (cp == 7806) return true; + if (cp == 7808) return true; + if (cp == 7810) return true; + if (cp == 7812) return true; + if (cp == 7814) return true; + if (cp == 7816) return true; + if (cp == 7818) return true; + if (cp == 7820) return true; + if (cp == 7822) return true; + if (cp == 7824) return true; + if (cp == 7826) return true; + if (cp == 7828) return true; + if (cp == 7838) return true; + if (cp == 7840) return true; + if (cp == 7842) return true; + if (cp == 7844) return true; + if (cp == 7846) return true; + if (cp == 7848) return true; + if (cp == 7850) return true; + if (cp == 7852) return true; + if (cp == 7854) return true; + if (cp == 7856) return true; + if (cp == 7858) return true; + if (cp == 7860) return true; + if (cp == 7862) return true; + if (cp == 7864) return true; + if (cp == 7866) return true; + if (cp == 7868) return true; + if (cp == 7870) return true; + if (cp == 7872) return true; + if (cp == 7874) return true; + if (cp == 7876) return true; + if (cp == 7878) return true; + if (cp == 7880) return true; + if (cp == 7882) return true; + if (cp == 7884) return true; + if (cp == 7886) return true; + if (cp == 7888) return true; + if (cp == 7890) return true; + if (cp == 7892) return true; + if (cp == 7894) return true; + if (cp == 7896) return true; + if (cp == 7898) return true; + if (cp == 7900) return true; + if (cp == 7902) return true; + if (cp == 7904) return true; + if (cp == 7906) return true; + if (cp == 7908) return true; + if (cp == 7910) return true; + if (cp == 7912) return true; + if (cp == 7914) return true; + if (cp == 7916) return true; + if (cp == 7918) return true; + if (cp == 7920) return true; + if (cp == 7922) return true; + if (cp == 7924) return true; + if (cp == 7926) return true; + if (cp == 7928) return true; + if (cp == 7930) return true; + if (cp == 7932) return true; + if (cp == 7934) return true; + if (cp >= 7944 && cp <= 7951) return true; + if (cp >= 7960 && cp <= 7965) return true; + if (cp >= 7976 && cp <= 7983) return true; + if (cp >= 7992 && cp <= 7999) return true; + if (cp >= 8008 && cp <= 8013) return true; + if (cp == 8025) return true; + if (cp == 8027) return true; + if (cp == 8029) return true; + if (cp == 8031) return true; + if (cp >= 8040 && cp <= 8047) return true; + if (cp >= 8120 && cp <= 8123) return true; + if (cp >= 8136 && cp <= 8139) return true; + if (cp >= 8152 && cp <= 8155) return true; + if (cp >= 8168 && cp <= 8172) return true; + if (cp >= 8184 && cp <= 8187) return true; + if (cp == 8450) return true; + if (cp == 8455) return true; + if (cp >= 8459 && cp <= 8461) return true; + if (cp >= 8464 && cp <= 8466) return true; + if (cp == 8469) return true; + if (cp >= 8473 && cp <= 8477) return true; + if (cp == 8484) return true; + if (cp == 8486) return true; + if (cp == 8488) return true; + if (cp >= 8490 && cp <= 8493) return true; + if (cp >= 8496 && cp <= 8499) return true; + if (cp >= 8510 && cp <= 8511) return true; + if (cp == 8517) return true; + if (cp >= 8544 && cp <= 8559) return true; + if (cp == 8579) return true; + if (cp >= 9398 && cp <= 9423) return true; + if (cp >= 11264 && cp <= 11310) return true; + if (cp == 11360) return true; + if (cp >= 11362 && cp <= 11364) return true; + if (cp == 11367) return true; + if (cp == 11369) return true; + if (cp == 11371) return true; + if (cp >= 11373 && cp <= 11376) return true; + if (cp == 11378) return true; + if (cp == 11381) return true; + if (cp >= 11390 && cp <= 11392) return true; + if (cp == 11394) return true; + if (cp == 11396) return true; + if (cp == 11398) return true; + if (cp == 11400) return true; + if (cp == 11402) return true; + if (cp == 11404) return true; + if (cp == 11406) return true; + if (cp == 11408) return true; + if (cp == 11410) return true; + if (cp == 11412) return true; + if (cp == 11414) return true; + if (cp == 11416) return true; + if (cp == 11418) return true; + if (cp == 11420) return true; + if (cp == 11422) return true; + if (cp == 11424) return true; + if (cp == 11426) return true; + if (cp == 11428) return true; + if (cp == 11430) return true; + if (cp == 11432) return true; + if (cp == 11434) return true; + if (cp == 11436) return true; + if (cp == 11438) return true; + if (cp == 11440) return true; + if (cp == 11442) return true; + if (cp == 11444) return true; + if (cp == 11446) return true; + if (cp == 11448) return true; + if (cp == 11450) return true; + if (cp == 11452) return true; + if (cp == 11454) return true; + if (cp == 11456) return true; + if (cp == 11458) return true; + if (cp == 11460) return true; + if (cp == 11462) return true; + if (cp == 11464) return true; + if (cp == 11466) return true; + if (cp == 11468) return true; + if (cp == 11470) return true; + if (cp == 11472) return true; + if (cp == 11474) return true; + if (cp == 11476) return true; + if (cp == 11478) return true; + if (cp == 11480) return true; + if (cp == 11482) return true; + if (cp == 11484) return true; + if (cp == 11486) return true; + if (cp == 11488) return true; + if (cp == 11490) return true; + if (cp == 11499) return true; + if (cp == 11501) return true; + if (cp == 11506) return true; + if (cp == 42560) return true; + if (cp == 42562) return true; + if (cp == 42564) return true; + if (cp == 42566) return true; + if (cp == 42568) return true; + if (cp == 42570) return true; + if (cp == 42572) return true; + if (cp == 42574) return true; + if (cp == 42576) return true; + if (cp == 42578) return true; + if (cp == 42580) return true; + if (cp == 42582) return true; + if (cp == 42584) return true; + if (cp == 42586) return true; + if (cp == 42588) return true; + if (cp == 42590) return true; + if (cp == 42592) return true; + if (cp == 42594) return true; + if (cp == 42596) return true; + if (cp == 42598) return true; + if (cp == 42600) return true; + if (cp == 42602) return true; + if (cp == 42604) return true; + if (cp == 42624) return true; + if (cp == 42626) return true; + if (cp == 42628) return true; + if (cp == 42630) return true; + if (cp == 42632) return true; + if (cp == 42634) return true; + if (cp == 42636) return true; + if (cp == 42638) return true; + if (cp == 42640) return true; + if (cp == 42642) return true; + if (cp == 42644) return true; + if (cp == 42646) return true; + if (cp == 42648) return true; + if (cp == 42650) return true; + if (cp == 42786) return true; + if (cp == 42788) return true; + if (cp == 42790) return true; + if (cp == 42792) return true; + if (cp == 42794) return true; + if (cp == 42796) return true; + if (cp == 42798) return true; + if (cp == 42802) return true; + if (cp == 42804) return true; + if (cp == 42806) return true; + if (cp == 42808) return true; + if (cp == 42810) return true; + if (cp == 42812) return true; + if (cp == 42814) return true; + if (cp == 42816) return true; + if (cp == 42818) return true; + if (cp == 42820) return true; + if (cp == 42822) return true; + if (cp == 42824) return true; + if (cp == 42826) return true; + if (cp == 42828) return true; + if (cp == 42830) return true; + if (cp == 42832) return true; + if (cp == 42834) return true; + if (cp == 42836) return true; + if (cp == 42838) return true; + if (cp == 42840) return true; + if (cp == 42842) return true; + if (cp == 42844) return true; + if (cp == 42846) return true; + if (cp == 42848) return true; + if (cp == 42850) return true; + if (cp == 42852) return true; + if (cp == 42854) return true; + if (cp == 42856) return true; + if (cp == 42858) return true; + if (cp == 42860) return true; + if (cp == 42862) return true; + if (cp == 42873) return true; + if (cp == 42875) return true; + if (cp >= 42877 && cp <= 42878) return true; + if (cp == 42880) return true; + if (cp == 42882) return true; + if (cp == 42884) return true; + if (cp == 42886) return true; + if (cp == 42891) return true; + if (cp == 42893) return true; + if (cp == 42896) return true; + if (cp == 42898) return true; + if (cp == 42902) return true; + if (cp == 42904) return true; + if (cp == 42906) return true; + if (cp == 42908) return true; + if (cp == 42910) return true; + if (cp == 42912) return true; + if (cp == 42914) return true; + if (cp == 42916) return true; + if (cp == 42918) return true; + if (cp == 42920) return true; + if (cp >= 42922 && cp <= 42926) return true; + if (cp >= 42928 && cp <= 42932) return true; + if (cp == 42934) return true; + if (cp >= 65313 && cp <= 65338) return true; + if (cp >= 66560 && cp <= 66599) return true; + if (cp >= 66736 && cp <= 66771) return true; + if (cp >= 68736 && cp <= 68786) return true; + if (cp >= 71840 && cp <= 71871) return true; + if (cp >= 119808 && cp <= 119833) return true; + if (cp >= 119860 && cp <= 119885) return true; + if (cp >= 119912 && cp <= 119937) return true; + if (cp == 119964) return true; + if (cp >= 119966 && cp <= 119967) return true; + if (cp == 119970) return true; + if (cp >= 119973 && cp <= 119974) return true; + if (cp >= 119977 && cp <= 119980) return true; + if (cp >= 119982 && cp <= 119989) return true; + if (cp >= 120016 && cp <= 120041) return true; + if (cp >= 120068 && cp <= 120069) return true; + if (cp >= 120071 && cp <= 120074) return true; + if (cp >= 120077 && cp <= 120084) return true; + if (cp >= 120086 && cp <= 120092) return true; + if (cp >= 120120 && cp <= 120121) return true; + if (cp >= 120123 && cp <= 120126) return true; + if (cp >= 120128 && cp <= 120132) return true; + if (cp == 120134) return true; + if (cp >= 120138 && cp <= 120144) return true; + if (cp >= 120172 && cp <= 120197) return true; + if (cp >= 120224 && cp <= 120249) return true; + if (cp >= 120276 && cp <= 120301) return true; + if (cp >= 120328 && cp <= 120353) return true; + if (cp >= 120380 && cp <= 120405) return true; + if (cp >= 120432 && cp <= 120457) return true; + if (cp >= 120488 && cp <= 120512) return true; + if (cp >= 120546 && cp <= 120570) return true; + if (cp >= 120604 && cp <= 120628) return true; + if (cp >= 120662 && cp <= 120686) return true; + if (cp >= 120720 && cp <= 120744) return true; + if (cp == 120778) return true; + if (cp >= 125184 && cp <= 125217) return true; + if (cp >= 127280 && cp <= 127305) return true; + if (cp >= 127312 && cp <= 127337) return true; + if (cp >= 127344 && cp <= 127369) return true; + + return false; +} + +function isAlpha(c) { + var cp = ord(c); + + if (cp >= 65 && cp <= 90) return true; + if (cp >= 97 && cp <= 122) return true; + if (cp == 170) return true; + if (cp == 181) return true; + if (cp == 186) return true; + if (cp >= 192 && cp <= 214) return true; + if (cp >= 216 && cp <= 246) return true; + if (cp >= 248 && cp <= 705) return true; + if (cp >= 710 && cp <= 721) return true; + if (cp >= 736 && cp <= 740) return true; + if (cp == 748) return true; + if (cp == 750) return true; + if (cp == 837) return true; + if (cp >= 880 && cp <= 884) return true; + if (cp >= 886 && cp <= 887) return true; + if (cp >= 890 && cp <= 893) return true; + if (cp == 895) return true; + if (cp == 902) return true; + if (cp >= 904 && cp <= 906) return true; + if (cp == 908) return true; + if (cp >= 910 && cp <= 929) return true; + if (cp >= 931 && cp <= 1013) return true; + if (cp >= 1015 && cp <= 1153) return true; + if (cp >= 1162 && cp <= 1327) return true; + if (cp >= 1329 && cp <= 1366) return true; + if (cp == 1369) return true; + if (cp >= 1377 && cp <= 1415) return true; + if (cp >= 1456 && cp <= 1469) return true; + if (cp == 1471) return true; + if (cp >= 1473 && cp <= 1474) return true; + if (cp >= 1476 && cp <= 1477) return true; + if (cp == 1479) return true; + if (cp >= 1488 && cp <= 1514) return true; + if (cp >= 1520 && cp <= 1522) return true; + if (cp >= 1552 && cp <= 1562) return true; + if (cp >= 1568 && cp <= 1623) return true; + if (cp >= 1625 && cp <= 1631) return true; + if (cp >= 1646 && cp <= 1747) return true; + if (cp >= 1749 && cp <= 1756) return true; + if (cp >= 1761 && cp <= 1768) return true; + if (cp >= 1773 && cp <= 1775) return true; + if (cp >= 1786 && cp <= 1788) return true; + if (cp == 1791) return true; + if (cp >= 1808 && cp <= 1855) return true; + if (cp >= 1869 && cp <= 1969) return true; + if (cp >= 1994 && cp <= 2026) return true; + if (cp >= 2036 && cp <= 2037) return true; + if (cp == 2042) return true; + if (cp >= 2048 && cp <= 2071) return true; + if (cp >= 2074 && cp <= 2092) return true; + if (cp >= 2112 && cp <= 2136) return true; + if (cp >= 2144 && cp <= 2154) return true; + if (cp >= 2208 && cp <= 2228) return true; + if (cp >= 2230 && cp <= 2237) return true; + if (cp >= 2260 && cp <= 2271) return true; + if (cp >= 2275 && cp <= 2281) return true; + if (cp >= 2288 && cp <= 2363) return true; + if (cp >= 2365 && cp <= 2380) return true; + if (cp >= 2382 && cp <= 2384) return true; + if (cp >= 2389 && cp <= 2403) return true; + if (cp >= 2417 && cp <= 2435) return true; + if (cp >= 2437 && cp <= 2444) return true; + if (cp >= 2447 && cp <= 2448) return true; + if (cp >= 2451 && cp <= 2472) return true; + if (cp >= 2474 && cp <= 2480) return true; + if (cp == 2482) return true; + if (cp >= 2486 && cp <= 2489) return true; + if (cp >= 2493 && cp <= 2500) return true; + if (cp >= 2503 && cp <= 2504) return true; + if (cp >= 2507 && cp <= 2508) return true; + if (cp == 2510) return true; + if (cp == 2519) return true; + if (cp >= 2524 && cp <= 2525) return true; + if (cp >= 2527 && cp <= 2531) return true; + if (cp >= 2544 && cp <= 2545) return true; + if (cp == 2556) return true; + if (cp >= 2561 && cp <= 2563) return true; + if (cp >= 2565 && cp <= 2570) return true; + if (cp >= 2575 && cp <= 2576) return true; + if (cp >= 2579 && cp <= 2600) return true; + if (cp >= 2602 && cp <= 2608) return true; + if (cp >= 2610 && cp <= 2611) return true; + if (cp >= 2613 && cp <= 2614) return true; + if (cp >= 2616 && cp <= 2617) return true; + if (cp >= 2622 && cp <= 2626) return true; + if (cp >= 2631 && cp <= 2632) return true; + if (cp >= 2635 && cp <= 2636) return true; + if (cp == 2641) return true; + if (cp >= 2649 && cp <= 2652) return true; + if (cp == 2654) return true; + if (cp >= 2672 && cp <= 2677) return true; + if (cp >= 2689 && cp <= 2691) return true; + if (cp >= 2693 && cp <= 2701) return true; + if (cp >= 2703 && cp <= 2705) return true; + if (cp >= 2707 && cp <= 2728) return true; + if (cp >= 2730 && cp <= 2736) return true; + if (cp >= 2738 && cp <= 2739) return true; + if (cp >= 2741 && cp <= 2745) return true; + if (cp >= 2749 && cp <= 2757) return true; + if (cp >= 2759 && cp <= 2761) return true; + if (cp >= 2763 && cp <= 2764) return true; + if (cp == 2768) return true; + if (cp >= 2784 && cp <= 2787) return true; + if (cp >= 2809 && cp <= 2812) return true; + if (cp >= 2817 && cp <= 2819) return true; + if (cp >= 2821 && cp <= 2828) return true; + if (cp >= 2831 && cp <= 2832) return true; + if (cp >= 2835 && cp <= 2856) return true; + if (cp >= 2858 && cp <= 2864) return true; + if (cp >= 2866 && cp <= 2867) return true; + if (cp >= 2869 && cp <= 2873) return true; + if (cp >= 2877 && cp <= 2884) return true; + if (cp >= 2887 && cp <= 2888) return true; + if (cp >= 2891 && cp <= 2892) return true; + if (cp >= 2902 && cp <= 2903) return true; + if (cp >= 2908 && cp <= 2909) return true; + if (cp >= 2911 && cp <= 2915) return true; + if (cp == 2929) return true; + if (cp >= 2946 && cp <= 2947) return true; + if (cp >= 2949 && cp <= 2954) return true; + if (cp >= 2958 && cp <= 2960) return true; + if (cp >= 2962 && cp <= 2965) return true; + if (cp >= 2969 && cp <= 2970) return true; + if (cp == 2972) return true; + if (cp >= 2974 && cp <= 2975) return true; + if (cp >= 2979 && cp <= 2980) return true; + if (cp >= 2984 && cp <= 2986) return true; + if (cp >= 2990 && cp <= 3001) return true; + if (cp >= 3006 && cp <= 3010) return true; + if (cp >= 3014 && cp <= 3016) return true; + if (cp >= 3018 && cp <= 3020) return true; + if (cp == 3024) return true; + if (cp == 3031) return true; + if (cp >= 3072 && cp <= 3075) return true; + if (cp >= 3077 && cp <= 3084) return true; + if (cp >= 3086 && cp <= 3088) return true; + if (cp >= 3090 && cp <= 3112) return true; + if (cp >= 3114 && cp <= 3129) return true; + if (cp >= 3133 && cp <= 3140) return true; + if (cp >= 3142 && cp <= 3144) return true; + if (cp >= 3146 && cp <= 3148) return true; + if (cp >= 3157 && cp <= 3158) return true; + if (cp >= 3160 && cp <= 3162) return true; + if (cp >= 3168 && cp <= 3171) return true; + if (cp >= 3200 && cp <= 3203) return true; + if (cp >= 3205 && cp <= 3212) return true; + if (cp >= 3214 && cp <= 3216) return true; + if (cp >= 3218 && cp <= 3240) return true; + if (cp >= 3242 && cp <= 3251) return true; + if (cp >= 3253 && cp <= 3257) return true; + if (cp >= 3261 && cp <= 3268) return true; + if (cp >= 3270 && cp <= 3272) return true; + if (cp >= 3274 && cp <= 3276) return true; + if (cp >= 3285 && cp <= 3286) return true; + if (cp == 3294) return true; + if (cp >= 3296 && cp <= 3299) return true; + if (cp >= 3313 && cp <= 3314) return true; + if (cp >= 3328 && cp <= 3331) return true; + if (cp >= 3333 && cp <= 3340) return true; + if (cp >= 3342 && cp <= 3344) return true; + if (cp >= 3346 && cp <= 3386) return true; + if (cp >= 3389 && cp <= 3396) return true; + if (cp >= 3398 && cp <= 3400) return true; + if (cp >= 3402 && cp <= 3404) return true; + if (cp == 3406) return true; + if (cp >= 3412 && cp <= 3415) return true; + if (cp >= 3423 && cp <= 3427) return true; + if (cp >= 3450 && cp <= 3455) return true; + if (cp >= 3458 && cp <= 3459) return true; + if (cp >= 3461 && cp <= 3478) return true; + if (cp >= 3482 && cp <= 3505) return true; + if (cp >= 3507 && cp <= 3515) return true; + if (cp == 3517) return true; + if (cp >= 3520 && cp <= 3526) return true; + if (cp >= 3535 && cp <= 3540) return true; + if (cp == 3542) return true; + if (cp >= 3544 && cp <= 3551) return true; + if (cp >= 3570 && cp <= 3571) return true; + if (cp >= 3585 && cp <= 3642) return true; + if (cp >= 3648 && cp <= 3654) return true; + if (cp == 3661) return true; + if (cp >= 3713 && cp <= 3714) return true; + if (cp == 3716) return true; + if (cp >= 3719 && cp <= 3720) return true; + if (cp == 3722) return true; + if (cp == 3725) return true; + if (cp >= 3732 && cp <= 3735) return true; + if (cp >= 3737 && cp <= 3743) return true; + if (cp >= 3745 && cp <= 3747) return true; + if (cp == 3749) return true; + if (cp == 3751) return true; + if (cp >= 3754 && cp <= 3755) return true; + if (cp >= 3757 && cp <= 3769) return true; + if (cp >= 3771 && cp <= 3773) return true; + if (cp >= 3776 && cp <= 3780) return true; + if (cp == 3782) return true; + if (cp == 3789) return true; + if (cp >= 3804 && cp <= 3807) return true; + if (cp == 3840) return true; + if (cp >= 3904 && cp <= 3911) return true; + if (cp >= 3913 && cp <= 3948) return true; + if (cp >= 3953 && cp <= 3969) return true; + if (cp >= 3976 && cp <= 3991) return true; + if (cp >= 3993 && cp <= 4028) return true; + if (cp >= 4096 && cp <= 4150) return true; + if (cp == 4152) return true; + if (cp >= 4155 && cp <= 4159) return true; + if (cp >= 4176 && cp <= 4194) return true; + if (cp >= 4197 && cp <= 4200) return true; + if (cp >= 4206 && cp <= 4230) return true; + if (cp == 4238) return true; + if (cp >= 4252 && cp <= 4253) return true; + if (cp >= 4256 && cp <= 4293) return true; + if (cp == 4295) return true; + if (cp == 4301) return true; + if (cp >= 4304 && cp <= 4346) return true; + if (cp >= 4348 && cp <= 4680) return true; + if (cp >= 4682 && cp <= 4685) return true; + if (cp >= 4688 && cp <= 4694) return true; + if (cp == 4696) return true; + if (cp >= 4698 && cp <= 4701) return true; + if (cp >= 4704 && cp <= 4744) return true; + if (cp >= 4746 && cp <= 4749) return true; + if (cp >= 4752 && cp <= 4784) return true; + if (cp >= 4786 && cp <= 4789) return true; + if (cp >= 4792 && cp <= 4798) return true; + if (cp == 4800) return true; + if (cp >= 4802 && cp <= 4805) return true; + if (cp >= 4808 && cp <= 4822) return true; + if (cp >= 4824 && cp <= 4880) return true; + if (cp >= 4882 && cp <= 4885) return true; + if (cp >= 4888 && cp <= 4954) return true; + if (cp == 4959) return true; + if (cp >= 4992 && cp <= 5007) return true; + if (cp >= 5024 && cp <= 5109) return true; + if (cp >= 5112 && cp <= 5117) return true; + if (cp >= 5121 && cp <= 5740) return true; + if (cp >= 5743 && cp <= 5759) return true; + if (cp >= 5761 && cp <= 5786) return true; + if (cp >= 5792 && cp <= 5866) return true; + if (cp >= 5870 && cp <= 5880) return true; + if (cp >= 5888 && cp <= 5900) return true; + if (cp >= 5902 && cp <= 5907) return true; + if (cp >= 5920 && cp <= 5939) return true; + if (cp >= 5952 && cp <= 5971) return true; + if (cp >= 5984 && cp <= 5996) return true; + if (cp >= 5998 && cp <= 6000) return true; + if (cp >= 6002 && cp <= 6003) return true; + if (cp >= 6016 && cp <= 6067) return true; + if (cp >= 6070 && cp <= 6088) return true; + if (cp == 6103) return true; + if (cp == 6108) return true; + if (cp >= 6176 && cp <= 6263) return true; + if (cp >= 6272 && cp <= 6314) return true; + if (cp >= 6320 && cp <= 6389) return true; + if (cp >= 6400 && cp <= 6430) return true; + if (cp >= 6432 && cp <= 6443) return true; + if (cp >= 6448 && cp <= 6456) return true; + if (cp >= 6480 && cp <= 6509) return true; + if (cp >= 6512 && cp <= 6516) return true; + if (cp >= 6528 && cp <= 6571) return true; + if (cp >= 6576 && cp <= 6601) return true; + if (cp >= 6656 && cp <= 6683) return true; + if (cp >= 6688 && cp <= 6750) return true; + if (cp >= 6753 && cp <= 6772) return true; + if (cp == 6823) return true; + if (cp >= 6912 && cp <= 6963) return true; + if (cp >= 6965 && cp <= 6979) return true; + if (cp >= 6981 && cp <= 6987) return true; + if (cp >= 7040 && cp <= 7081) return true; + if (cp >= 7084 && cp <= 7087) return true; + if (cp >= 7098 && cp <= 7141) return true; + if (cp >= 7143 && cp <= 7153) return true; + if (cp >= 7168 && cp <= 7221) return true; + if (cp >= 7245 && cp <= 7247) return true; + if (cp >= 7258 && cp <= 7293) return true; + if (cp >= 7296 && cp <= 7304) return true; + if (cp >= 7401 && cp <= 7404) return true; + if (cp >= 7406 && cp <= 7411) return true; + if (cp >= 7413 && cp <= 7414) return true; + if (cp >= 7424 && cp <= 7615) return true; + if (cp >= 7655 && cp <= 7668) return true; + if (cp >= 7680 && cp <= 7957) return true; + if (cp >= 7960 && cp <= 7965) return true; + if (cp >= 7968 && cp <= 8005) return true; + if (cp >= 8008 && cp <= 8013) return true; + if (cp >= 8016 && cp <= 8023) return true; + if (cp == 8025) return true; + if (cp == 8027) return true; + if (cp == 8029) return true; + if (cp >= 8031 && cp <= 8061) return true; + if (cp >= 8064 && cp <= 8116) return true; + if (cp >= 8118 && cp <= 8124) return true; + if (cp == 8126) return true; + if (cp >= 8130 && cp <= 8132) return true; + if (cp >= 8134 && cp <= 8140) return true; + if (cp >= 8144 && cp <= 8147) return true; + if (cp >= 8150 && cp <= 8155) return true; + if (cp >= 8160 && cp <= 8172) return true; + if (cp >= 8178 && cp <= 8180) return true; + if (cp >= 8182 && cp <= 8188) return true; + if (cp == 8305) return true; + if (cp == 8319) return true; + if (cp >= 8336 && cp <= 8348) return true; + if (cp == 8450) return true; + if (cp == 8455) return true; + if (cp >= 8458 && cp <= 8467) return true; + if (cp == 8469) return true; + if (cp >= 8473 && cp <= 8477) return true; + if (cp == 8484) return true; + if (cp == 8486) return true; + if (cp == 8488) return true; + if (cp >= 8490 && cp <= 8493) return true; + if (cp >= 8495 && cp <= 8505) return true; + if (cp >= 8508 && cp <= 8511) return true; + if (cp >= 8517 && cp <= 8521) return true; + if (cp == 8526) return true; + if (cp >= 8544 && cp <= 8584) return true; + if (cp >= 9398 && cp <= 9449) return true; + if (cp >= 11264 && cp <= 11310) return true; + if (cp >= 11312 && cp <= 11358) return true; + if (cp >= 11360 && cp <= 11492) return true; + if (cp >= 11499 && cp <= 11502) return true; + if (cp >= 11506 && cp <= 11507) return true; + if (cp >= 11520 && cp <= 11557) return true; + if (cp == 11559) return true; + if (cp == 11565) return true; + if (cp >= 11568 && cp <= 11623) return true; + if (cp == 11631) return true; + if (cp >= 11648 && cp <= 11670) return true; + if (cp >= 11680 && cp <= 11686) return true; + if (cp >= 11688 && cp <= 11694) return true; + if (cp >= 11696 && cp <= 11702) return true; + if (cp >= 11704 && cp <= 11710) return true; + if (cp >= 11712 && cp <= 11718) return true; + if (cp >= 11720 && cp <= 11726) return true; + if (cp >= 11728 && cp <= 11734) return true; + if (cp >= 11736 && cp <= 11742) return true; + if (cp >= 11744 && cp <= 11775) return true; + if (cp == 11823) return true; + if (cp >= 12293 && cp <= 12295) return true; + if (cp >= 12321 && cp <= 12329) return true; + if (cp >= 12337 && cp <= 12341) return true; + if (cp >= 12344 && cp <= 12348) return true; + if (cp >= 12353 && cp <= 12438) return true; + if (cp >= 12445 && cp <= 12447) return true; + if (cp >= 12449 && cp <= 12538) return true; + if (cp >= 12540 && cp <= 12543) return true; + if (cp >= 12549 && cp <= 12590) return true; + if (cp >= 12593 && cp <= 12686) return true; + if (cp >= 12704 && cp <= 12730) return true; + if (cp >= 12784 && cp <= 12799) return true; + if (cp >= 13312 && cp <= 19893) return true; + if (cp >= 19968 && cp <= 40938) return true; + if (cp >= 40960 && cp <= 42124) return true; + if (cp >= 42192 && cp <= 42237) return true; + if (cp >= 42240 && cp <= 42508) return true; + if (cp >= 42512 && cp <= 42527) return true; + if (cp >= 42538 && cp <= 42539) return true; + if (cp >= 42560 && cp <= 42606) return true; + if (cp >= 42612 && cp <= 42619) return true; + if (cp >= 42623 && cp <= 42735) return true; + if (cp >= 42775 && cp <= 42783) return true; + if (cp >= 42786 && cp <= 42888) return true; + if (cp >= 42891 && cp <= 42926) return true; + if (cp >= 42928 && cp <= 42935) return true; + if (cp >= 42999 && cp <= 43009) return true; + if (cp >= 43011 && cp <= 43013) return true; + if (cp >= 43015 && cp <= 43018) return true; + if (cp >= 43020 && cp <= 43047) return true; + if (cp >= 43072 && cp <= 43123) return true; + if (cp >= 43136 && cp <= 43203) return true; + if (cp == 43205) return true; + if (cp >= 43250 && cp <= 43255) return true; + if (cp == 43259) return true; + if (cp == 43261) return true; + if (cp >= 43274 && cp <= 43306) return true; + if (cp >= 43312 && cp <= 43346) return true; + if (cp >= 43360 && cp <= 43388) return true; + if (cp >= 43392 && cp <= 43442) return true; + if (cp >= 43444 && cp <= 43455) return true; + if (cp == 43471) return true; + if (cp >= 43488 && cp <= 43492) return true; + if (cp >= 43494 && cp <= 43503) return true; + if (cp >= 43514 && cp <= 43518) return true; + if (cp >= 43520 && cp <= 43574) return true; + if (cp >= 43584 && cp <= 43597) return true; + if (cp >= 43616 && cp <= 43638) return true; + if (cp == 43642) return true; + if (cp >= 43646 && cp <= 43710) return true; + if (cp == 43712) return true; + if (cp == 43714) return true; + if (cp >= 43739 && cp <= 43741) return true; + if (cp >= 43744 && cp <= 43759) return true; + if (cp >= 43762 && cp <= 43765) return true; + if (cp >= 43777 && cp <= 43782) return true; + if (cp >= 43785 && cp <= 43790) return true; + if (cp >= 43793 && cp <= 43798) return true; + if (cp >= 43808 && cp <= 43814) return true; + if (cp >= 43816 && cp <= 43822) return true; + if (cp >= 43824 && cp <= 43866) return true; + if (cp >= 43868 && cp <= 43877) return true; + if (cp >= 43888 && cp <= 44010) return true; + if (cp >= 44032 && cp <= 55203) return true; + if (cp >= 55216 && cp <= 55238) return true; + if (cp >= 55243 && cp <= 55291) return true; + if (cp >= 63744 && cp <= 64109) return true; + if (cp >= 64112 && cp <= 64217) return true; + if (cp >= 64256 && cp <= 64262) return true; + if (cp >= 64275 && cp <= 64279) return true; + if (cp >= 64285 && cp <= 64296) return true; + if (cp >= 64298 && cp <= 64310) return true; + if (cp >= 64312 && cp <= 64316) return true; + if (cp == 64318) return true; + if (cp >= 64320 && cp <= 64321) return true; + if (cp >= 64323 && cp <= 64324) return true; + if (cp >= 64326 && cp <= 64433) return true; + if (cp >= 64467 && cp <= 64829) return true; + if (cp >= 64848 && cp <= 64911) return true; + if (cp >= 64914 && cp <= 64967) return true; + if (cp >= 65008 && cp <= 65019) return true; + if (cp >= 65136 && cp <= 65140) return true; + if (cp >= 65142 && cp <= 65276) return true; + if (cp >= 65313 && cp <= 65338) return true; + if (cp >= 65345 && cp <= 65370) return true; + if (cp >= 65382 && cp <= 65470) return true; + if (cp >= 65474 && cp <= 65479) return true; + if (cp >= 65482 && cp <= 65487) return true; + if (cp >= 65490 && cp <= 65495) return true; + if (cp >= 65498 && cp <= 65500) return true; + if (cp >= 65536 && cp <= 65547) return true; + if (cp >= 65549 && cp <= 65574) return true; + if (cp >= 65576 && cp <= 65594) return true; + if (cp >= 65596 && cp <= 65597) return true; + if (cp >= 65599 && cp <= 65613) return true; + if (cp >= 65616 && cp <= 65629) return true; + if (cp >= 65664 && cp <= 65786) return true; + if (cp >= 65856 && cp <= 65908) return true; + if (cp >= 66176 && cp <= 66204) return true; + if (cp >= 66208 && cp <= 66256) return true; + if (cp >= 66304 && cp <= 66335) return true; + if (cp >= 66349 && cp <= 66378) return true; + if (cp >= 66384 && cp <= 66426) return true; + if (cp >= 66432 && cp <= 66461) return true; + if (cp >= 66464 && cp <= 66499) return true; + if (cp >= 66504 && cp <= 66511) return true; + if (cp >= 66513 && cp <= 66517) return true; + if (cp >= 66560 && cp <= 66717) return true; + if (cp >= 66736 && cp <= 66771) return true; + if (cp >= 66776 && cp <= 66811) return true; + if (cp >= 66816 && cp <= 66855) return true; + if (cp >= 66864 && cp <= 66915) return true; + if (cp >= 67072 && cp <= 67382) return true; + if (cp >= 67392 && cp <= 67413) return true; + if (cp >= 67424 && cp <= 67431) return true; + if (cp >= 67584 && cp <= 67589) return true; + if (cp == 67592) return true; + if (cp >= 67594 && cp <= 67637) return true; + if (cp >= 67639 && cp <= 67640) return true; + if (cp == 67644) return true; + if (cp >= 67647 && cp <= 67669) return true; + if (cp >= 67680 && cp <= 67702) return true; + if (cp >= 67712 && cp <= 67742) return true; + if (cp >= 67808 && cp <= 67826) return true; + if (cp >= 67828 && cp <= 67829) return true; + if (cp >= 67840 && cp <= 67861) return true; + if (cp >= 67872 && cp <= 67897) return true; + if (cp >= 67968 && cp <= 68023) return true; + if (cp >= 68030 && cp <= 68031) return true; + if (cp >= 68096 && cp <= 68099) return true; + if (cp >= 68101 && cp <= 68102) return true; + if (cp >= 68108 && cp <= 68115) return true; + if (cp >= 68117 && cp <= 68119) return true; + if (cp >= 68121 && cp <= 68147) return true; + if (cp >= 68192 && cp <= 68220) return true; + if (cp >= 68224 && cp <= 68252) return true; + if (cp >= 68288 && cp <= 68295) return true; + if (cp >= 68297 && cp <= 68324) return true; + if (cp >= 68352 && cp <= 68405) return true; + if (cp >= 68416 && cp <= 68437) return true; + if (cp >= 68448 && cp <= 68466) return true; + if (cp >= 68480 && cp <= 68497) return true; + if (cp >= 68608 && cp <= 68680) return true; + if (cp >= 68736 && cp <= 68786) return true; + if (cp >= 68800 && cp <= 68850) return true; + if (cp >= 69632 && cp <= 69701) return true; + if (cp >= 69762 && cp <= 69816) return true; + if (cp >= 69840 && cp <= 69864) return true; + if (cp >= 69888 && cp <= 69938) return true; + if (cp >= 69968 && cp <= 70002) return true; + if (cp == 70006) return true; + if (cp >= 70016 && cp <= 70079) return true; + if (cp >= 70081 && cp <= 70084) return true; + if (cp == 70106) return true; + if (cp == 70108) return true; + if (cp >= 70144 && cp <= 70161) return true; + if (cp >= 70163 && cp <= 70196) return true; + if (cp == 70199) return true; + if (cp == 70206) return true; + if (cp >= 70272 && cp <= 70278) return true; + if (cp == 70280) return true; + if (cp >= 70282 && cp <= 70285) return true; + if (cp >= 70287 && cp <= 70301) return true; + if (cp >= 70303 && cp <= 70312) return true; + if (cp >= 70320 && cp <= 70376) return true; + if (cp >= 70400 && cp <= 70403) return true; + if (cp >= 70405 && cp <= 70412) return true; + if (cp >= 70415 && cp <= 70416) return true; + if (cp >= 70419 && cp <= 70440) return true; + if (cp >= 70442 && cp <= 70448) return true; + if (cp >= 70450 && cp <= 70451) return true; + if (cp >= 70453 && cp <= 70457) return true; + if (cp >= 70461 && cp <= 70468) return true; + if (cp >= 70471 && cp <= 70472) return true; + if (cp >= 70475 && cp <= 70476) return true; + if (cp == 70480) return true; + if (cp == 70487) return true; + if (cp >= 70493 && cp <= 70499) return true; + if (cp >= 70656 && cp <= 70721) return true; + if (cp >= 70723 && cp <= 70725) return true; + if (cp >= 70727 && cp <= 70730) return true; + if (cp >= 70784 && cp <= 70849) return true; + if (cp >= 70852 && cp <= 70853) return true; + if (cp == 70855) return true; + if (cp >= 71040 && cp <= 71093) return true; + if (cp >= 71096 && cp <= 71102) return true; + if (cp >= 71128 && cp <= 71133) return true; + if (cp >= 71168 && cp <= 71230) return true; + if (cp == 71232) return true; + if (cp == 71236) return true; + if (cp >= 71296 && cp <= 71349) return true; + if (cp >= 71424 && cp <= 71449) return true; + if (cp >= 71453 && cp <= 71466) return true; + if (cp >= 71840 && cp <= 71903) return true; + if (cp == 71935) return true; + if (cp >= 72192 && cp <= 72242) return true; + if (cp >= 72245 && cp <= 72254) return true; + if (cp >= 72272 && cp <= 72323) return true; + if (cp >= 72326 && cp <= 72343) return true; + if (cp >= 72384 && cp <= 72440) return true; + if (cp >= 72704 && cp <= 72712) return true; + if (cp >= 72714 && cp <= 72758) return true; + if (cp >= 72760 && cp <= 72766) return true; + if (cp == 72768) return true; + if (cp >= 72818 && cp <= 72847) return true; + if (cp >= 72850 && cp <= 72871) return true; + if (cp >= 72873 && cp <= 72886) return true; + if (cp >= 72960 && cp <= 72966) return true; + if (cp >= 72968 && cp <= 72969) return true; + if (cp >= 72971 && cp <= 73014) return true; + if (cp == 73018) return true; + if (cp >= 73020 && cp <= 73021) return true; + if (cp >= 73023 && cp <= 73025) return true; + if (cp == 73027) return true; + if (cp >= 73030 && cp <= 73031) return true; + if (cp >= 73728 && cp <= 74649) return true; + if (cp >= 74752 && cp <= 74862) return true; + if (cp >= 74880 && cp <= 75075) return true; + if (cp >= 77824 && cp <= 78894) return true; + if (cp >= 82944 && cp <= 83526) return true; + if (cp >= 92160 && cp <= 92728) return true; + if (cp >= 92736 && cp <= 92766) return true; + if (cp >= 92880 && cp <= 92909) return true; + if (cp >= 92928 && cp <= 92982) return true; + if (cp >= 92992 && cp <= 92995) return true; + if (cp >= 93027 && cp <= 93047) return true; + if (cp >= 93053 && cp <= 93071) return true; + if (cp >= 93952 && cp <= 94020) return true; + if (cp >= 94032 && cp <= 94078) return true; + if (cp >= 94099 && cp <= 94111) return true; + if (cp >= 94176 && cp <= 94177) return true; + if (cp >= 94208 && cp <= 100332) return true; + if (cp >= 100352 && cp <= 101106) return true; + if (cp >= 110592 && cp <= 110878) return true; + if (cp >= 110960 && cp <= 111355) return true; + if (cp >= 113664 && cp <= 113770) return true; + if (cp >= 113776 && cp <= 113788) return true; + if (cp >= 113792 && cp <= 113800) return true; + if (cp >= 113808 && cp <= 113817) return true; + if (cp == 113822) return true; + if (cp >= 119808 && cp <= 119892) return true; + if (cp >= 119894 && cp <= 119964) return true; + if (cp >= 119966 && cp <= 119967) return true; + if (cp == 119970) return true; + if (cp >= 119973 && cp <= 119974) return true; + if (cp >= 119977 && cp <= 119980) return true; + if (cp >= 119982 && cp <= 119993) return true; + if (cp == 119995) return true; + if (cp >= 119997 && cp <= 120003) return true; + if (cp >= 120005 && cp <= 120069) return true; + if (cp >= 120071 && cp <= 120074) return true; + if (cp >= 120077 && cp <= 120084) return true; + if (cp >= 120086 && cp <= 120092) return true; + if (cp >= 120094 && cp <= 120121) return true; + if (cp >= 120123 && cp <= 120126) return true; + if (cp >= 120128 && cp <= 120132) return true; + if (cp == 120134) return true; + if (cp >= 120138 && cp <= 120144) return true; + if (cp >= 120146 && cp <= 120485) return true; + if (cp >= 120488 && cp <= 120512) return true; + if (cp >= 120514 && cp <= 120538) return true; + if (cp >= 120540 && cp <= 120570) return true; + if (cp >= 120572 && cp <= 120596) return true; + if (cp >= 120598 && cp <= 120628) return true; + if (cp >= 120630 && cp <= 120654) return true; + if (cp >= 120656 && cp <= 120686) return true; + if (cp >= 120688 && cp <= 120712) return true; + if (cp >= 120714 && cp <= 120744) return true; + if (cp >= 120746 && cp <= 120770) return true; + if (cp >= 120772 && cp <= 120779) return true; + if (cp >= 122880 && cp <= 122886) return true; + if (cp >= 122888 && cp <= 122904) return true; + if (cp >= 122907 && cp <= 122913) return true; + if (cp >= 122915 && cp <= 122916) return true; + if (cp >= 122918 && cp <= 122922) return true; + if (cp >= 124928 && cp <= 125124) return true; + if (cp >= 125184 && cp <= 125251) return true; + if (cp == 125255) return true; + if (cp >= 126464 && cp <= 126467) return true; + if (cp >= 126469 && cp <= 126495) return true; + if (cp >= 126497 && cp <= 126498) return true; + if (cp == 126500) return true; + if (cp == 126503) return true; + if (cp >= 126505 && cp <= 126514) return true; + if (cp >= 126516 && cp <= 126519) return true; + if (cp == 126521) return true; + if (cp == 126523) return true; + if (cp == 126530) return true; + if (cp == 126535) return true; + if (cp == 126537) return true; + if (cp == 126539) return true; + if (cp >= 126541 && cp <= 126543) return true; + if (cp >= 126545 && cp <= 126546) return true; + if (cp == 126548) return true; + if (cp == 126551) return true; + if (cp == 126553) return true; + if (cp == 126555) return true; + if (cp == 126557) return true; + if (cp == 126559) return true; + if (cp >= 126561 && cp <= 126562) return true; + if (cp == 126564) return true; + if (cp >= 126567 && cp <= 126570) return true; + if (cp >= 126572 && cp <= 126578) return true; + if (cp >= 126580 && cp <= 126583) return true; + if (cp >= 126585 && cp <= 126588) return true; + if (cp == 126590) return true; + if (cp >= 126592 && cp <= 126601) return true; + if (cp >= 126603 && cp <= 126619) return true; + if (cp >= 126625 && cp <= 126627) return true; + if (cp >= 126629 && cp <= 126633) return true; + if (cp >= 126635 && cp <= 126651) return true; + if (cp >= 127280 && cp <= 127305) return true; + if (cp >= 127312 && cp <= 127337) return true; + if (cp >= 127344 && cp <= 127369) return true; + if (cp >= 131072 && cp <= 173782) return true; + if (cp >= 173824 && cp <= 177972) return true; + if (cp >= 177984 && cp <= 178205) return true; + if (cp >= 178208 && cp <= 183969) return true; + if (cp >= 183984 && cp <= 191456) return true; + if (cp >= 194560 && cp <= 195101) return true; + + return false; +} + +function isDigit(c) { + var cp = ord(c); + if (cp >= 48 && cp <= 57) + return true; + if (cp >= 1632 && cp <= 1641) + return true; + if (cp >= 1776 && cp <= 1785) + return true; + if (cp >= 1984 && cp <= 1993) + return true; + if (cp >= 2406 && cp <= 2415) + return true; + if (cp >= 2534 && cp <= 2543) + return true; + if (cp >= 2662 && cp <= 2671) + return true; + if (cp >= 2790 && cp <= 2799) + return true; + if (cp >= 2918 && cp <= 2927) + return true; + if (cp >= 3046 && cp <= 3055) + return true; + if (cp >= 3174 && cp <= 3183) + return true; + if (cp >= 3302 && cp <= 3311) + return true; + if (cp >= 3430 && cp <= 3439) + return true; + if (cp >= 3558 && cp <= 3567) + return true; + if (cp >= 3664 && cp <= 3673) + return true; + if (cp >= 3792 && cp <= 3801) + return true; + if (cp >= 3872 && cp <= 3881) + return true; + if (cp >= 4160 && cp <= 4169) + return true; + if (cp >= 4240 && cp <= 4249) + return true; + if (cp >= 6112 && cp <= 6121) + return true; + if (cp >= 6160 && cp <= 6169) + return true; + if (cp >= 6470 && cp <= 6479) + return true; + if (cp >= 6608 && cp <= 6617) + return true; + if (cp >= 6784 && cp <= 6793) + return true; + if (cp >= 6800 && cp <= 6809) + return true; + if (cp >= 6992 && cp <= 7001) + return true; + if (cp >= 7088 && cp <= 7097) + return true; + if (cp >= 7232 && cp <= 7241) + return true; + if (cp >= 7248 && cp <= 7257) + return true; + if (cp >= 42528 && cp <= 42537) + return true; + if (cp >= 43216 && cp <= 43225) + return true; + if (cp >= 43264 && cp <= 43273) + return true; + if (cp >= 43472 && cp <= 43481) + return true; + if (cp >= 43504 && cp <= 43513) + return true; + if (cp >= 43600 && cp <= 43609) + return true; + if (cp >= 44016 && cp <= 44025) + return true; + if (cp >= 65296 && cp <= 65305) + return true; + if (cp >= 66720 && cp <= 66729) + return true; + if (cp >= 69734 && cp <= 69743) + return true; + if (cp >= 69872 && cp <= 69881) + return true; + if (cp >= 69942 && cp <= 69951) + return true; + if (cp >= 70096 && cp <= 70105) + return true; + if (cp >= 70384 && cp <= 70393) + return true; + if (cp >= 70736 && cp <= 70745) + return true; + if (cp >= 70864 && cp <= 70873) + return true; + if (cp >= 71248 && cp <= 71257) + return true; + if (cp >= 71360 && cp <= 71369) + return true; + if (cp >= 71472 && cp <= 71481) + return true; + if (cp >= 71904 && cp <= 71913) + return true; + if (cp >= 72784 && cp <= 72793) + return true; + if (cp >= 73040 && cp <= 73049) + return true; + if (cp >= 92768 && cp <= 92777) + return true; + if (cp >= 93008 && cp <= 93017) + return true; + if (cp >= 120782 && cp <= 120831) + return true; + if (cp >= 125264 && cp <= 125273) + return true; + + return false; +} + function isAlnum(c) { return isAlpha(c) || isDigit(c); } -function isBlank(c) { return c == ' ' || c == '\t'; } -function isSpace(c) { return isBlank(c) || c == '\r' || c == '\n'; } -function isXdigit(c) { return isDigit(c) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'); } -function ord(c) { return c.charCodeAt(0); } -function isPrint(c) { return ord(c) > 31 && ord(c) < 127; } -function toLower(c) { return c.toLowerCase(); } -function toUpper(c) { return c.toUpperCase(); } +function isBlank(c) { + var cp = ord(c); + if (cp == 9) + return true; + if (cp == 32) + return true; + if (cp == 160) + return true; + if (cp == 5760) + return true; + if (cp >= 8192 && cp <= 8202) + return true; + if (cp == 8239) + return true; + if (cp == 8287) + return true; + if (cp == 12288) + return true; + + return false; +} +function isSpace(c) { + var cp = ord(c); + if (cp >= 10 && cp <= 13) + return true; + if (cp == 133) + return true; + if (cp == 8232) + return true; + if (cp == 8233) + return true; + + return isBlank(c); +} +function isXdigit(c) { return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'); } + +function isPrint(c) { + var cp = ord(c); + if (cp >= 32 && cp <= 126) return true; + if (cp >= 160 && cp <= 887) return true; + if (cp >= 890 && cp <= 895) return true; + if (cp >= 900 && cp <= 906) return true; + if (cp == 908) return true; + if (cp >= 910 && cp <= 929) return true; + if (cp >= 931 && cp <= 1327) return true; + if (cp >= 1329 && cp <= 1366) return true; + if (cp >= 1369 && cp <= 1375) return true; + if (cp >= 1377 && cp <= 1415) return true; + if (cp >= 1417 && cp <= 1418) return true; + if (cp >= 1421 && cp <= 1423) return true; + if (cp >= 1425 && cp <= 1479) return true; + if (cp >= 1488 && cp <= 1514) return true; + if (cp >= 1520 && cp <= 1524) return true; + if (cp >= 1536 && cp <= 1564) return true; + if (cp >= 1566 && cp <= 1805) return true; + if (cp >= 1807 && cp <= 1866) return true; + if (cp >= 1869 && cp <= 1969) return true; + if (cp >= 1984 && cp <= 2042) return true; + if (cp >= 2048 && cp <= 2093) return true; + if (cp >= 2096 && cp <= 2110) return true; + if (cp >= 2112 && cp <= 2139) return true; + if (cp == 2142) return true; + if (cp >= 2144 && cp <= 2154) return true; + if (cp >= 2208 && cp <= 2228) return true; + if (cp >= 2230 && cp <= 2237) return true; + if (cp >= 2260 && cp <= 2435) return true; + if (cp >= 2437 && cp <= 2444) return true; + if (cp >= 2447 && cp <= 2448) return true; + if (cp >= 2451 && cp <= 2472) return true; + if (cp >= 2474 && cp <= 2480) return true; + if (cp == 2482) return true; + if (cp >= 2486 && cp <= 2489) return true; + if (cp >= 2492 && cp <= 2500) return true; + if (cp >= 2503 && cp <= 2504) return true; + if (cp >= 2507 && cp <= 2510) return true; + if (cp == 2519) return true; + if (cp >= 2524 && cp <= 2525) return true; + if (cp >= 2527 && cp <= 2531) return true; + if (cp >= 2534 && cp <= 2557) return true; + if (cp >= 2561 && cp <= 2563) return true; + if (cp >= 2565 && cp <= 2570) return true; + if (cp >= 2575 && cp <= 2576) return true; + if (cp >= 2579 && cp <= 2600) return true; + if (cp >= 2602 && cp <= 2608) return true; + if (cp >= 2610 && cp <= 2611) return true; + if (cp >= 2613 && cp <= 2614) return true; + if (cp >= 2616 && cp <= 2617) return true; + if (cp == 2620) return true; + if (cp >= 2622 && cp <= 2626) return true; + if (cp >= 2631 && cp <= 2632) return true; + if (cp >= 2635 && cp <= 2637) return true; + if (cp == 2641) return true; + if (cp >= 2649 && cp <= 2652) return true; + if (cp == 2654) return true; + if (cp >= 2662 && cp <= 2677) return true; + if (cp >= 2689 && cp <= 2691) return true; + if (cp >= 2693 && cp <= 2701) return true; + if (cp >= 2703 && cp <= 2705) return true; + if (cp >= 2707 && cp <= 2728) return true; + if (cp >= 2730 && cp <= 2736) return true; + if (cp >= 2738 && cp <= 2739) return true; + if (cp >= 2741 && cp <= 2745) return true; + if (cp >= 2748 && cp <= 2757) return true; + if (cp >= 2759 && cp <= 2761) return true; + if (cp >= 2763 && cp <= 2765) return true; + if (cp == 2768) return true; + if (cp >= 2784 && cp <= 2787) return true; + if (cp >= 2790 && cp <= 2801) return true; + if (cp >= 2809 && cp <= 2815) return true; + if (cp >= 2817 && cp <= 2819) return true; + if (cp >= 2821 && cp <= 2828) return true; + if (cp >= 2831 && cp <= 2832) return true; + if (cp >= 2835 && cp <= 2856) return true; + if (cp >= 2858 && cp <= 2864) return true; + if (cp >= 2866 && cp <= 2867) return true; + if (cp >= 2869 && cp <= 2873) return true; + if (cp >= 2876 && cp <= 2884) return true; + if (cp >= 2887 && cp <= 2888) return true; + if (cp >= 2891 && cp <= 2893) return true; + if (cp >= 2902 && cp <= 2903) return true; + if (cp >= 2908 && cp <= 2909) return true; + if (cp >= 2911 && cp <= 2915) return true; + if (cp >= 2918 && cp <= 2935) return true; + if (cp >= 2946 && cp <= 2947) return true; + if (cp >= 2949 && cp <= 2954) return true; + if (cp >= 2958 && cp <= 2960) return true; + if (cp >= 2962 && cp <= 2965) return true; + if (cp >= 2969 && cp <= 2970) return true; + if (cp == 2972) return true; + if (cp >= 2974 && cp <= 2975) return true; + if (cp >= 2979 && cp <= 2980) return true; + if (cp >= 2984 && cp <= 2986) return true; + if (cp >= 2990 && cp <= 3001) return true; + if (cp >= 3006 && cp <= 3010) return true; + if (cp >= 3014 && cp <= 3016) return true; + if (cp >= 3018 && cp <= 3021) return true; + if (cp == 3024) return true; + if (cp == 3031) return true; + if (cp >= 3046 && cp <= 3066) return true; + if (cp >= 3072 && cp <= 3075) return true; + if (cp >= 3077 && cp <= 3084) return true; + if (cp >= 3086 && cp <= 3088) return true; + if (cp >= 3090 && cp <= 3112) return true; + if (cp >= 3114 && cp <= 3129) return true; + if (cp >= 3133 && cp <= 3140) return true; + if (cp >= 3142 && cp <= 3144) return true; + if (cp >= 3146 && cp <= 3149) return true; + if (cp >= 3157 && cp <= 3158) return true; + if (cp >= 3160 && cp <= 3162) return true; + if (cp >= 3168 && cp <= 3171) return true; + if (cp >= 3174 && cp <= 3183) return true; + if (cp >= 3192 && cp <= 3203) return true; + if (cp >= 3205 && cp <= 3212) return true; + if (cp >= 3214 && cp <= 3216) return true; + if (cp >= 3218 && cp <= 3240) return true; + if (cp >= 3242 && cp <= 3251) return true; + if (cp >= 3253 && cp <= 3257) return true; + if (cp >= 3260 && cp <= 3268) return true; + if (cp >= 3270 && cp <= 3272) return true; + if (cp >= 3274 && cp <= 3277) return true; + if (cp >= 3285 && cp <= 3286) return true; + if (cp == 3294) return true; + if (cp >= 3296 && cp <= 3299) return true; + if (cp >= 3302 && cp <= 3311) return true; + if (cp >= 3313 && cp <= 3314) return true; + if (cp >= 3328 && cp <= 3331) return true; + if (cp >= 3333 && cp <= 3340) return true; + if (cp >= 3342 && cp <= 3344) return true; + if (cp >= 3346 && cp <= 3396) return true; + if (cp >= 3398 && cp <= 3400) return true; + if (cp >= 3402 && cp <= 3407) return true; + if (cp >= 3412 && cp <= 3427) return true; + if (cp >= 3430 && cp <= 3455) return true; + if (cp >= 3458 && cp <= 3459) return true; + if (cp >= 3461 && cp <= 3478) return true; + if (cp >= 3482 && cp <= 3505) return true; + if (cp >= 3507 && cp <= 3515) return true; + if (cp == 3517) return true; + if (cp >= 3520 && cp <= 3526) return true; + if (cp == 3530) return true; + if (cp >= 3535 && cp <= 3540) return true; + if (cp == 3542) return true; + if (cp >= 3544 && cp <= 3551) return true; + if (cp >= 3558 && cp <= 3567) return true; + if (cp >= 3570 && cp <= 3572) return true; + if (cp >= 3585 && cp <= 3642) return true; + if (cp >= 3647 && cp <= 3675) return true; + if (cp >= 3713 && cp <= 3714) return true; + if (cp == 3716) return true; + if (cp >= 3719 && cp <= 3720) return true; + if (cp == 3722) return true; + if (cp == 3725) return true; + if (cp >= 3732 && cp <= 3735) return true; + if (cp >= 3737 && cp <= 3743) return true; + if (cp >= 3745 && cp <= 3747) return true; + if (cp == 3749) return true; + if (cp == 3751) return true; + if (cp >= 3754 && cp <= 3755) return true; + if (cp >= 3757 && cp <= 3769) return true; + if (cp >= 3771 && cp <= 3773) return true; + if (cp >= 3776 && cp <= 3780) return true; + if (cp == 3782) return true; + if (cp >= 3784 && cp <= 3789) return true; + if (cp >= 3792 && cp <= 3801) return true; + if (cp >= 3804 && cp <= 3807) return true; + if (cp >= 3840 && cp <= 3911) return true; + if (cp >= 3913 && cp <= 3948) return true; + if (cp >= 3953 && cp <= 3991) return true; + if (cp >= 3993 && cp <= 4028) return true; + if (cp >= 4030 && cp <= 4044) return true; + if (cp >= 4046 && cp <= 4058) return true; + if (cp >= 4096 && cp <= 4293) return true; + if (cp == 4295) return true; + if (cp == 4301) return true; + if (cp >= 4304 && cp <= 4680) return true; + if (cp >= 4682 && cp <= 4685) return true; + if (cp >= 4688 && cp <= 4694) return true; + if (cp == 4696) return true; + if (cp >= 4698 && cp <= 4701) return true; + if (cp >= 4704 && cp <= 4744) return true; + if (cp >= 4746 && cp <= 4749) return true; + if (cp >= 4752 && cp <= 4784) return true; + if (cp >= 4786 && cp <= 4789) return true; + if (cp >= 4792 && cp <= 4798) return true; + if (cp == 4800) return true; + if (cp >= 4802 && cp <= 4805) return true; + if (cp >= 4808 && cp <= 4822) return true; + if (cp >= 4824 && cp <= 4880) return true; + if (cp >= 4882 && cp <= 4885) return true; + if (cp >= 4888 && cp <= 4954) return true; + if (cp >= 4957 && cp <= 4988) return true; + if (cp >= 4992 && cp <= 5017) return true; + if (cp >= 5024 && cp <= 5109) return true; + if (cp >= 5112 && cp <= 5117) return true; + if (cp >= 5120 && cp <= 5788) return true; + if (cp >= 5792 && cp <= 5880) return true; + if (cp >= 5888 && cp <= 5900) return true; + if (cp >= 5902 && cp <= 5908) return true; + if (cp >= 5920 && cp <= 5942) return true; + if (cp >= 5952 && cp <= 5971) return true; + if (cp >= 5984 && cp <= 5996) return true; + if (cp >= 5998 && cp <= 6000) return true; + if (cp >= 6002 && cp <= 6003) return true; + if (cp >= 6016 && cp <= 6109) return true; + if (cp >= 6112 && cp <= 6121) return true; + if (cp >= 6128 && cp <= 6137) return true; + if (cp >= 6144 && cp <= 6158) return true; + if (cp >= 6160 && cp <= 6169) return true; + if (cp >= 6176 && cp <= 6263) return true; + if (cp >= 6272 && cp <= 6314) return true; + if (cp >= 6320 && cp <= 6389) return true; + if (cp >= 6400 && cp <= 6430) return true; + if (cp >= 6432 && cp <= 6443) return true; + if (cp >= 6448 && cp <= 6459) return true; + if (cp == 6464) return true; + if (cp >= 6468 && cp <= 6509) return true; + if (cp >= 6512 && cp <= 6516) return true; + if (cp >= 6528 && cp <= 6571) return true; + if (cp >= 6576 && cp <= 6601) return true; + if (cp >= 6608 && cp <= 6618) return true; + if (cp >= 6622 && cp <= 6683) return true; + if (cp >= 6686 && cp <= 6750) return true; + if (cp >= 6752 && cp <= 6780) return true; + if (cp >= 6783 && cp <= 6793) return true; + if (cp >= 6800 && cp <= 6809) return true; + if (cp >= 6816 && cp <= 6829) return true; + if (cp >= 6832 && cp <= 6846) return true; + if (cp >= 6912 && cp <= 6987) return true; + if (cp >= 6992 && cp <= 7036) return true; + if (cp >= 7040 && cp <= 7155) return true; + if (cp >= 7164 && cp <= 7223) return true; + if (cp >= 7227 && cp <= 7241) return true; + if (cp >= 7245 && cp <= 7304) return true; + if (cp >= 7360 && cp <= 7367) return true; + if (cp >= 7376 && cp <= 7417) return true; + if (cp >= 7424 && cp <= 7673) return true; + if (cp >= 7675 && cp <= 7957) return true; + if (cp >= 7960 && cp <= 7965) return true; + if (cp >= 7968 && cp <= 8005) return true; + if (cp >= 8008 && cp <= 8013) return true; + if (cp >= 8016 && cp <= 8023) return true; + if (cp == 8025) return true; + if (cp == 8027) return true; + if (cp == 8029) return true; + if (cp >= 8031 && cp <= 8061) return true; + if (cp >= 8064 && cp <= 8116) return true; + if (cp >= 8118 && cp <= 8132) return true; + if (cp >= 8134 && cp <= 8147) return true; + if (cp >= 8150 && cp <= 8155) return true; + if (cp >= 8157 && cp <= 8175) return true; + if (cp >= 8178 && cp <= 8180) return true; + if (cp >= 8182 && cp <= 8190) return true; + if (cp >= 8192 && cp <= 8231) return true; + if (cp >= 8234 && cp <= 8292) return true; + if (cp >= 8294 && cp <= 8305) return true; + if (cp >= 8308 && cp <= 8334) return true; + if (cp >= 8336 && cp <= 8348) return true; + if (cp >= 8352 && cp <= 8383) return true; + if (cp >= 8400 && cp <= 8432) return true; + if (cp >= 8448 && cp <= 8587) return true; + if (cp >= 8592 && cp <= 9254) return true; + if (cp >= 9280 && cp <= 9290) return true; + if (cp >= 9312 && cp <= 11123) return true; + if (cp >= 11126 && cp <= 11157) return true; + if (cp >= 11160 && cp <= 11193) return true; + if (cp >= 11197 && cp <= 11208) return true; + if (cp >= 11210 && cp <= 11218) return true; + if (cp >= 11244 && cp <= 11247) return true; + if (cp >= 11264 && cp <= 11310) return true; + if (cp >= 11312 && cp <= 11358) return true; + if (cp >= 11360 && cp <= 11507) return true; + if (cp >= 11513 && cp <= 11557) return true; + if (cp == 11559) return true; + if (cp == 11565) return true; + if (cp >= 11568 && cp <= 11623) return true; + if (cp >= 11631 && cp <= 11632) return true; + if (cp >= 11647 && cp <= 11670) return true; + if (cp >= 11680 && cp <= 11686) return true; + if (cp >= 11688 && cp <= 11694) return true; + if (cp >= 11696 && cp <= 11702) return true; + if (cp >= 11704 && cp <= 11710) return true; + if (cp >= 11712 && cp <= 11718) return true; + if (cp >= 11720 && cp <= 11726) return true; + if (cp >= 11728 && cp <= 11734) return true; + if (cp >= 11736 && cp <= 11742) return true; + if (cp >= 11744 && cp <= 11849) return true; + if (cp >= 11904 && cp <= 11929) return true; + if (cp >= 11931 && cp <= 12019) return true; + if (cp >= 12032 && cp <= 12245) return true; + if (cp >= 12272 && cp <= 12283) return true; + if (cp >= 12288 && cp <= 12351) return true; + if (cp >= 12353 && cp <= 12438) return true; + if (cp >= 12441 && cp <= 12543) return true; + if (cp >= 12549 && cp <= 12590) return true; + if (cp >= 12593 && cp <= 12686) return true; + if (cp >= 12688 && cp <= 12730) return true; + if (cp >= 12736 && cp <= 12771) return true; + if (cp >= 12784 && cp <= 12830) return true; + if (cp >= 12832 && cp <= 13054) return true; + if (cp >= 13056 && cp <= 19893) return true; + if (cp >= 19904 && cp <= 40938) return true; + if (cp >= 40960 && cp <= 42124) return true; + if (cp >= 42128 && cp <= 42182) return true; + if (cp >= 42192 && cp <= 42539) return true; + if (cp >= 42560 && cp <= 42743) return true; + if (cp >= 42752 && cp <= 42926) return true; + if (cp >= 42928 && cp <= 42935) return true; + if (cp >= 42999 && cp <= 43051) return true; + if (cp >= 43056 && cp <= 43065) return true; + if (cp >= 43072 && cp <= 43127) return true; + if (cp >= 43136 && cp <= 43205) return true; + if (cp >= 43214 && cp <= 43225) return true; + if (cp >= 43232 && cp <= 43261) return true; + if (cp >= 43264 && cp <= 43347) return true; + if (cp >= 43359 && cp <= 43388) return true; + if (cp >= 43392 && cp <= 43469) return true; + if (cp >= 43471 && cp <= 43481) return true; + if (cp >= 43486 && cp <= 43518) return true; + if (cp >= 43520 && cp <= 43574) return true; + if (cp >= 43584 && cp <= 43597) return true; + if (cp >= 43600 && cp <= 43609) return true; + if (cp >= 43612 && cp <= 43714) return true; + if (cp >= 43739 && cp <= 43766) return true; + if (cp >= 43777 && cp <= 43782) return true; + if (cp >= 43785 && cp <= 43790) return true; + if (cp >= 43793 && cp <= 43798) return true; + if (cp >= 43808 && cp <= 43814) return true; + if (cp >= 43816 && cp <= 43822) return true; + if (cp >= 43824 && cp <= 43877) return true; + if (cp >= 43888 && cp <= 44013) return true; + if (cp >= 44016 && cp <= 44025) return true; + if (cp >= 44032 && cp <= 55203) return true; + if (cp >= 55216 && cp <= 55238) return true; + if (cp >= 55243 && cp <= 55291) return true; + if (cp >= 57344 && cp <= 64109) return true; + if (cp >= 64112 && cp <= 64217) return true; + if (cp >= 64256 && cp <= 64262) return true; + if (cp >= 64275 && cp <= 64279) return true; + if (cp >= 64285 && cp <= 64310) return true; + if (cp >= 64312 && cp <= 64316) return true; + if (cp == 64318) return true; + if (cp >= 64320 && cp <= 64321) return true; + if (cp >= 64323 && cp <= 64324) return true; + if (cp >= 64326 && cp <= 64449) return true; + if (cp >= 64467 && cp <= 64831) return true; + if (cp >= 64848 && cp <= 64911) return true; + if (cp >= 64914 && cp <= 64967) return true; + if (cp >= 65008 && cp <= 65021) return true; + if (cp >= 65024 && cp <= 65049) return true; + if (cp >= 65056 && cp <= 65106) return true; + if (cp >= 65108 && cp <= 65126) return true; + if (cp >= 65128 && cp <= 65131) return true; + if (cp >= 65136 && cp <= 65140) return true; + if (cp >= 65142 && cp <= 65276) return true; + if (cp == 65279) return true; + if (cp >= 65281 && cp <= 65470) return true; + if (cp >= 65474 && cp <= 65479) return true; + if (cp >= 65482 && cp <= 65487) return true; + if (cp >= 65490 && cp <= 65495) return true; + if (cp >= 65498 && cp <= 65500) return true; + if (cp >= 65504 && cp <= 65510) return true; + if (cp >= 65512 && cp <= 65518) return true; + if (cp >= 65529 && cp <= 65533) return true; + if (cp >= 65536 && cp <= 65547) return true; + if (cp >= 65549 && cp <= 65574) return true; + if (cp >= 65576 && cp <= 65594) return true; + if (cp >= 65596 && cp <= 65597) return true; + if (cp >= 65599 && cp <= 65613) return true; + if (cp >= 65616 && cp <= 65629) return true; + if (cp >= 65664 && cp <= 65786) return true; + if (cp >= 65792 && cp <= 65794) return true; + if (cp >= 65799 && cp <= 65843) return true; + if (cp >= 65847 && cp <= 65934) return true; + if (cp >= 65936 && cp <= 65947) return true; + if (cp == 65952) return true; + if (cp >= 66000 && cp <= 66045) return true; + if (cp >= 66176 && cp <= 66204) return true; + if (cp >= 66208 && cp <= 66256) return true; + if (cp >= 66272 && cp <= 66299) return true; + if (cp >= 66304 && cp <= 66339) return true; + if (cp >= 66349 && cp <= 66378) return true; + if (cp >= 66384 && cp <= 66426) return true; + if (cp >= 66432 && cp <= 66461) return true; + if (cp >= 66463 && cp <= 66499) return true; + if (cp >= 66504 && cp <= 66517) return true; + if (cp >= 66560 && cp <= 66717) return true; + if (cp >= 66720 && cp <= 66729) return true; + if (cp >= 66736 && cp <= 66771) return true; + if (cp >= 66776 && cp <= 66811) return true; + if (cp >= 66816 && cp <= 66855) return true; + if (cp >= 66864 && cp <= 66915) return true; + if (cp == 66927) return true; + if (cp >= 67072 && cp <= 67382) return true; + if (cp >= 67392 && cp <= 67413) return true; + if (cp >= 67424 && cp <= 67431) return true; + if (cp >= 67584 && cp <= 67589) return true; + if (cp == 67592) return true; + if (cp >= 67594 && cp <= 67637) return true; + if (cp >= 67639 && cp <= 67640) return true; + if (cp == 67644) return true; + if (cp >= 67647 && cp <= 67669) return true; + if (cp >= 67671 && cp <= 67742) return true; + if (cp >= 67751 && cp <= 67759) return true; + if (cp >= 67808 && cp <= 67826) return true; + if (cp >= 67828 && cp <= 67829) return true; + if (cp >= 67835 && cp <= 67867) return true; + if (cp >= 67871 && cp <= 67897) return true; + if (cp == 67903) return true; + if (cp >= 67968 && cp <= 68023) return true; + if (cp >= 68028 && cp <= 68047) return true; + if (cp >= 68050 && cp <= 68099) return true; + if (cp >= 68101 && cp <= 68102) return true; + if (cp >= 68108 && cp <= 68115) return true; + if (cp >= 68117 && cp <= 68119) return true; + if (cp >= 68121 && cp <= 68147) return true; + if (cp >= 68152 && cp <= 68154) return true; + if (cp >= 68159 && cp <= 68167) return true; + if (cp >= 68176 && cp <= 68184) return true; + if (cp >= 68192 && cp <= 68255) return true; + if (cp >= 68288 && cp <= 68326) return true; + if (cp >= 68331 && cp <= 68342) return true; + if (cp >= 68352 && cp <= 68405) return true; + if (cp >= 68409 && cp <= 68437) return true; + if (cp >= 68440 && cp <= 68466) return true; + if (cp >= 68472 && cp <= 68497) return true; + if (cp >= 68505 && cp <= 68508) return true; + if (cp >= 68521 && cp <= 68527) return true; + if (cp >= 68608 && cp <= 68680) return true; + if (cp >= 68736 && cp <= 68786) return true; + if (cp >= 68800 && cp <= 68850) return true; + if (cp >= 68858 && cp <= 68863) return true; + if (cp >= 69216 && cp <= 69246) return true; + if (cp >= 69632 && cp <= 69709) return true; + if (cp >= 69714 && cp <= 69743) return true; + if (cp >= 69759 && cp <= 69825) return true; + if (cp >= 69840 && cp <= 69864) return true; + if (cp >= 69872 && cp <= 69881) return true; + if (cp >= 69888 && cp <= 69940) return true; + if (cp >= 69942 && cp <= 69955) return true; + if (cp >= 69968 && cp <= 70006) return true; + if (cp >= 70016 && cp <= 70093) return true; + if (cp >= 70096 && cp <= 70111) return true; + if (cp >= 70113 && cp <= 70132) return true; + if (cp >= 70144 && cp <= 70161) return true; + if (cp >= 70163 && cp <= 70206) return true; + if (cp >= 70272 && cp <= 70278) return true; + if (cp == 70280) return true; + if (cp >= 70282 && cp <= 70285) return true; + if (cp >= 70287 && cp <= 70301) return true; + if (cp >= 70303 && cp <= 70313) return true; + if (cp >= 70320 && cp <= 70378) return true; + if (cp >= 70384 && cp <= 70393) return true; + if (cp >= 70400 && cp <= 70403) return true; + if (cp >= 70405 && cp <= 70412) return true; + if (cp >= 70415 && cp <= 70416) return true; + if (cp >= 70419 && cp <= 70440) return true; + if (cp >= 70442 && cp <= 70448) return true; + if (cp >= 70450 && cp <= 70451) return true; + if (cp >= 70453 && cp <= 70457) return true; + if (cp >= 70460 && cp <= 70468) return true; + if (cp >= 70471 && cp <= 70472) return true; + if (cp >= 70475 && cp <= 70477) return true; + if (cp == 70480) return true; + if (cp == 70487) return true; + if (cp >= 70493 && cp <= 70499) return true; + if (cp >= 70502 && cp <= 70508) return true; + if (cp >= 70512 && cp <= 70516) return true; + if (cp >= 70656 && cp <= 70745) return true; + if (cp == 70747) return true; + if (cp == 70749) return true; + if (cp >= 70784 && cp <= 70855) return true; + if (cp >= 70864 && cp <= 70873) return true; + if (cp >= 71040 && cp <= 71093) return true; + if (cp >= 71096 && cp <= 71133) return true; + if (cp >= 71168 && cp <= 71236) return true; + if (cp >= 71248 && cp <= 71257) return true; + if (cp >= 71264 && cp <= 71276) return true; + if (cp >= 71296 && cp <= 71351) return true; + if (cp >= 71360 && cp <= 71369) return true; + if (cp >= 71424 && cp <= 71449) return true; + if (cp >= 71453 && cp <= 71467) return true; + if (cp >= 71472 && cp <= 71487) return true; + if (cp >= 71840 && cp <= 71922) return true; + if (cp == 71935) return true; + if (cp >= 72192 && cp <= 72263) return true; + if (cp >= 72272 && cp <= 72323) return true; + if (cp >= 72326 && cp <= 72348) return true; + if (cp >= 72350 && cp <= 72354) return true; + if (cp >= 72384 && cp <= 72440) return true; + if (cp >= 72704 && cp <= 72712) return true; + if (cp >= 72714 && cp <= 72758) return true; + if (cp >= 72760 && cp <= 72773) return true; + if (cp >= 72784 && cp <= 72812) return true; + if (cp >= 72816 && cp <= 72847) return true; + if (cp >= 72850 && cp <= 72871) return true; + if (cp >= 72873 && cp <= 72886) return true; + if (cp >= 72960 && cp <= 72966) return true; + if (cp >= 72968 && cp <= 72969) return true; + if (cp >= 72971 && cp <= 73014) return true; + if (cp == 73018) return true; + if (cp >= 73020 && cp <= 73021) return true; + if (cp >= 73023 && cp <= 73031) return true; + if (cp >= 73040 && cp <= 73049) return true; + if (cp >= 73728 && cp <= 74649) return true; + if (cp >= 74752 && cp <= 74862) return true; + if (cp >= 74864 && cp <= 74868) return true; + if (cp >= 74880 && cp <= 75075) return true; + if (cp >= 77824 && cp <= 78894) return true; + if (cp >= 82944 && cp <= 83526) return true; + if (cp >= 92160 && cp <= 92728) return true; + if (cp >= 92736 && cp <= 92766) return true; + if (cp >= 92768 && cp <= 92777) return true; + if (cp >= 92782 && cp <= 92783) return true; + if (cp >= 92880 && cp <= 92909) return true; + if (cp >= 92912 && cp <= 92917) return true; + if (cp >= 92928 && cp <= 92997) return true; + if (cp >= 93008 && cp <= 93017) return true; + if (cp >= 93019 && cp <= 93025) return true; + if (cp >= 93027 && cp <= 93047) return true; + if (cp >= 93053 && cp <= 93071) return true; + if (cp >= 93952 && cp <= 94020) return true; + if (cp >= 94032 && cp <= 94078) return true; + if (cp >= 94095 && cp <= 94111) return true; + if (cp >= 94176 && cp <= 94177) return true; + if (cp >= 94208 && cp <= 100332) return true; + if (cp >= 100352 && cp <= 101106) return true; + if (cp >= 110592 && cp <= 110878) return true; + if (cp >= 110960 && cp <= 111355) return true; + if (cp >= 113664 && cp <= 113770) return true; + if (cp >= 113776 && cp <= 113788) return true; + if (cp >= 113792 && cp <= 113800) return true; + if (cp >= 113808 && cp <= 113817) return true; + if (cp >= 113820 && cp <= 113827) return true; + if (cp >= 118784 && cp <= 119029) return true; + if (cp >= 119040 && cp <= 119078) return true; + if (cp >= 119081 && cp <= 119272) return true; + if (cp >= 119296 && cp <= 119365) return true; + if (cp >= 119552 && cp <= 119638) return true; + if (cp >= 119648 && cp <= 119665) return true; + if (cp >= 119808 && cp <= 119892) return true; + if (cp >= 119894 && cp <= 119964) return true; + if (cp >= 119966 && cp <= 119967) return true; + if (cp == 119970) return true; + if (cp >= 119973 && cp <= 119974) return true; + if (cp >= 119977 && cp <= 119980) return true; + if (cp >= 119982 && cp <= 119993) return true; + if (cp == 119995) return true; + if (cp >= 119997 && cp <= 120003) return true; + if (cp >= 120005 && cp <= 120069) return true; + if (cp >= 120071 && cp <= 120074) return true; + if (cp >= 120077 && cp <= 120084) return true; + if (cp >= 120086 && cp <= 120092) return true; + if (cp >= 120094 && cp <= 120121) return true; + if (cp >= 120123 && cp <= 120126) return true; + if (cp >= 120128 && cp <= 120132) return true; + if (cp == 120134) return true; + if (cp >= 120138 && cp <= 120144) return true; + if (cp >= 120146 && cp <= 120485) return true; + if (cp >= 120488 && cp <= 120779) return true; + if (cp >= 120782 && cp <= 121483) return true; + if (cp >= 121499 && cp <= 121503) return true; + if (cp >= 121505 && cp <= 121519) return true; + if (cp >= 122880 && cp <= 122886) return true; + if (cp >= 122888 && cp <= 122904) return true; + if (cp >= 122907 && cp <= 122913) return true; + if (cp >= 122915 && cp <= 122916) return true; + if (cp >= 122918 && cp <= 122922) return true; + if (cp >= 124928 && cp <= 125124) return true; + if (cp >= 125127 && cp <= 125142) return true; + if (cp >= 125184 && cp <= 125258) return true; + if (cp >= 125264 && cp <= 125273) return true; + if (cp >= 125278 && cp <= 125279) return true; + if (cp >= 126464 && cp <= 126467) return true; + if (cp >= 126469 && cp <= 126495) return true; + if (cp >= 126497 && cp <= 126498) return true; + if (cp == 126500) return true; + if (cp == 126503) return true; + if (cp >= 126505 && cp <= 126514) return true; + if (cp >= 126516 && cp <= 126519) return true; + if (cp == 126521) return true; + if (cp == 126523) return true; + if (cp == 126530) return true; + if (cp == 126535) return true; + if (cp == 126537) return true; + if (cp == 126539) return true; + if (cp >= 126541 && cp <= 126543) return true; + if (cp >= 126545 && cp <= 126546) return true; + if (cp == 126548) return true; + if (cp == 126551) return true; + if (cp == 126553) return true; + if (cp == 126555) return true; + if (cp == 126557) return true; + if (cp == 126559) return true; + if (cp >= 126561 && cp <= 126562) return true; + if (cp == 126564) return true; + if (cp >= 126567 && cp <= 126570) return true; + if (cp >= 126572 && cp <= 126578) return true; + if (cp >= 126580 && cp <= 126583) return true; + if (cp >= 126585 && cp <= 126588) return true; + if (cp == 126590) return true; + if (cp >= 126592 && cp <= 126601) return true; + if (cp >= 126603 && cp <= 126619) return true; + if (cp >= 126625 && cp <= 126627) return true; + if (cp >= 126629 && cp <= 126633) return true; + if (cp >= 126635 && cp <= 126651) return true; + if (cp >= 126704 && cp <= 126705) return true; + if (cp >= 126976 && cp <= 127019) return true; + if (cp >= 127024 && cp <= 127123) return true; + if (cp >= 127136 && cp <= 127150) return true; + if (cp >= 127153 && cp <= 127167) return true; + if (cp >= 127169 && cp <= 127183) return true; + if (cp >= 127185 && cp <= 127221) return true; + if (cp >= 127232 && cp <= 127244) return true; + if (cp >= 127248 && cp <= 127278) return true; + if (cp >= 127280 && cp <= 127339) return true; + if (cp >= 127344 && cp <= 127404) return true; + if (cp >= 127462 && cp <= 127490) return true; + if (cp >= 127504 && cp <= 127547) return true; + if (cp >= 127552 && cp <= 127560) return true; + if (cp >= 127568 && cp <= 127569) return true; + if (cp >= 127584 && cp <= 127589) return true; + if (cp >= 127744 && cp <= 128724) return true; + if (cp >= 128736 && cp <= 128748) return true; + if (cp >= 128752 && cp <= 128760) return true; + if (cp >= 128768 && cp <= 128883) return true; + if (cp >= 128896 && cp <= 128980) return true; + if (cp >= 129024 && cp <= 129035) return true; + if (cp >= 129040 && cp <= 129095) return true; + if (cp >= 129104 && cp <= 129113) return true; + if (cp >= 129120 && cp <= 129159) return true; + if (cp >= 129168 && cp <= 129197) return true; + if (cp >= 129280 && cp <= 129291) return true; + if (cp >= 129296 && cp <= 129342) return true; + if (cp >= 129344 && cp <= 129356) return true; + if (cp >= 129360 && cp <= 129387) return true; + if (cp >= 129408 && cp <= 129431) return true; + if (cp == 129472) return true; + if (cp >= 129488 && cp <= 129510) return true; + if (cp >= 131072 && cp <= 173782) return true; + if (cp >= 173824 && cp <= 177972) return true; + if (cp >= 177984 && cp <= 178205) return true; + if (cp >= 178208 && cp <= 183969) return true; + if (cp >= 183984 && cp <= 191456) return true; + if (cp >= 194560 && cp <= 195101) return true; + return false; +} + +function toLower(c) { + var cp = ord(c); + + if (cp == 304) + return chr(105); + else if (cp >= 7312 && cp <= 7354) + return c; + else if (cp >= 7357 && cp <= 7359) + return c; + else if (cp == 42936) + return c; + else if (cp >= 93760 && cp <= 93791) + return c; + return c.toLowerCase(); +} + +function toUpper(c) { + var cp = ord(c); + if (cp == 223) + return c; + else if (cp == 329) + return c; + else if (cp == 496) + return c; + else if (cp == 912) + return c; + else if (cp == 944) + return c; + else if (cp == 1415) + return c; + else if (cp >= 4304 && cp <= 4346) + return c; + else if (cp >= 4349 && cp <= 4351) + return c; + else if (cp >= 7830 && cp <= 7834) + return c; + else if (cp == 8016) + return c; + else if (cp == 8018) + return c; + else if (cp == 8020) + return c; + else if (cp == 8022) + return c; + else if (cp >= 8064 && cp <= 8071) + return chr(cp + 8) + else if (cp >= 8072 && cp <= 8079) + return c; + else if (cp >= 8080 && cp <= 8087) + return chr(cp + 8); + else if (cp >= 8088 && cp <= 8095) + return c; + else if (cp >= 8096 && cp <= 8103) + return chr(cp + 8) + else if (cp >= 8104 && cp <= 8111) + return c; + else if (cp == 8114) + return c; + else if (cp == 8115) + return chr(8124); + else if (cp == 8116) + return c; + else if (cp == 8118) + return c; + else if (cp == 8119) + return c; + else if (cp == 8124) + return c; + else if (cp == 8130) + return c; + else if (cp == 8131) + return chr(8140); + else if (cp == 8132) + return c; + else if (cp == 8134) + return c; + else if (cp == 8135) + return c; + else if (cp == 8140) + return c; + else if (cp == 8146) + return c; + else if (cp == 8147) + return c; + else if (cp == 8150) + return c; + else if (cp == 8151) + return c; + else if (cp >= 8162 && cp <= 8164) + return c; + else if (cp == 8166) + return c; + else if (cp == 8167) + return c; + else if (cp == 8178) + return c; + else if (cp == 8179) + return chr(8188); + else if (cp == 8180) + return c; + else if (cp == 8182) + return c; + else if (cp == 8183) + return c; + else if (cp == 8188) + return c; + else if (cp == 42937) + return c; + else if (cp >= 64256 && cp <= 64262) + return c; + else if (cp >= 64275 && cp <= 64279) + return c; + else if (cp >= 93792 && cp <= 93823) + return c; + else + return c.toUpperCase(); +} // Lists @@ -48,7 +2912,7 @@ function cons(v, ls) { function rev(ls) { var acc = null; for (; ls; ls = ls.next) - acc = cons(ls.data, acc); + acc = cons(ls.data, acc); return acc; } function concat(ls1, ls2) { @@ -70,8 +2934,8 @@ function remove(x, ls) { for (; ls; ls = ls.next) if (ls.data == x) return concat(acc, ls.next); - else - acc = cons(ls.data, acc); + else + acc = cons(ls.data, acc); return ls; } @@ -220,11 +3084,11 @@ function stringToTime(string) { } /* -strftime() implementation from: -YUI 3.4.1 (build 4118) -Copyright 2011 Yahoo! Inc. All rights reserved. -Licensed under the BSD License. -http://yuilibrary.com/license/ + strftime() implementation from: + YUI 3.4.1 (build 4118) + Copyright 2011 Yahoo! Inc. All rights reserved. + Licensed under the BSD License. + http://yuilibrary.com/license/ */ var xPad=function (x, pad, r) @@ -1457,29 +4321,50 @@ function s2b(s) { return s == "True" ? true : s == "False" ? false : null; } function s2be(s) { return s == "True" ? true : s == "False" ? false : er("Illegal Boolean " ^ s); } function id(x) { return x; } -function sub(s, i) { return s.charAt(i); } -function suf(s, i) { return s.substring(i); } -function slen(s) { return s.length; } +function sub(s, i) { return Array.from(s)[i]; } +function suf(s, i) { return Array.from(s).slice(i).join(""); } +function slen(s) { return Array.from(s).length; } function sidx(s, ch) { - var r = s.indexOf(ch); + var r = Array.from(s).indexOf(ch); if (r == -1) return null; else return r; } function ssidx(h, n) { - var r = h.indexOf(n); - if (r == -1) - return null; - else - return r; + if (n == "") return 0; + var ah = Array.from(h); + var an = Array.from(n); + var i = 0, y = 0; + var top = ah.length - an.length + 1; + if (top < 0) top = 0; + var found = true; + + for(i = 0; i < top; ++i) { + found = true; + + for (y = 0; y < an.length; ++y) { + if (ah[i + y] != an[y]) { + found = false; + break; + } + } + + if (found) + return i; + } + return null; } + function sspn(s, chs) { - for (var i = 0; i < s.length; ++i) - if (chs.indexOf(s.charAt(i)) != -1) + var s2 = Array.from(s); + var chs2 = Array.from(chs); + + for (var i = 0; i < s2.length; ++i) + if (chs2.indexOf(s2[i]) != -1) return i; - return s.length; + return s2.length; } function schr(s, ch) { var r = s.indexOf(ch); @@ -1489,10 +4374,10 @@ function schr(s, ch) { return s.substring(r); } function ssub(s, start, len) { - return s.substring(start, start+len); + return Array.from(s).slice(start, start+len).join(""); } function strlenGe(s, len) { - return s.length >= len; + return slen(s) >= len; } function trimZeroes(s) { @@ -1591,11 +4476,11 @@ function strcmp(str1, str2) { } function chr(n) { - return String.fromCharCode(n); + return String.fromCodePoint(n); } function htmlifySpecialChar(ch) { - return "&#" + ch.charCodeAt(0) + ";"; + return "&#" + ch.codePointAt(0) + ";"; } @@ -2223,11 +5108,14 @@ function bless(s) { // Attribute name blessing +var maxCh = chr(127); function blessData(s) { - for (var i = 0; i < s.length; ++i) { - var c = s[i]; - if (!isAlnum(c) && c != '-' && c != '_') + var chars = Array.from(s); + + for (var i = 0; i < chars.length; ++i) { + var c = chars[i]; + if (c > maxCh || (!isAlnum(c) && c != '-' && c != '_')) er("Disallowed character in data-* attribute name"); } @@ -2238,9 +5126,11 @@ function blessData(s) { // CSS validation function atom(s) { - for (var i = 0; i < s.length; ++i) { - var c = s[i]; - if (!isAlnum(c) && c != '+' && c != '-' && c != '.' && c != '%' && c != '#') + var chars = Array.from(s); + + for (var i = 0; i < chars.length; ++i) { + var c = chars[i]; + if (c > maxCh || (!isAlnum(c) && c != '+' && c != '-' && c != '.' && c != '%' && c != '#')) er("Disallowed character in CSS atom"); } @@ -2248,10 +5138,12 @@ function atom(s) { } function css_url(s) { - for (var i = 0; i < s.length; ++i) { - var c = s[i]; - if (!isAlnum(c) && c != ':' && c != '/' && c != '.' && c != '_' && c != '+' - && c != '-' && c != '%' && c != '?' && c != '&' && c != '=' && c != '#') + var chars = Array.from(s); + + for (var i = 0; i < chars.length; ++i) { + var c = chars[i]; + if (c > maxCh || (!isAlnum(c) && c != ':' && c != '/' && c != '.' && c != '_' && c != '+' + && c != '-' && c != '%' && c != '?' && c != '&' && c != '=' && c != '#')) er("Disallowed character in CSS URL"); } @@ -2259,15 +5151,17 @@ function css_url(s) { } function property(s) { - if (s.length <= 0) + var chars = Array.from(s); + + if (chars.length <= 0) er("Empty CSS property"); - if (!isLower(s[0]) && s[0] != '_') + if (chars[0] > maxCh || (!isLower(chars[0]) && chars[0] != '_')) er("Bad initial character in CSS property"); - for (var i = 0; i < s.length; ++i) { - var c = s[i]; - if (!isLower(c) && !isDigit(c) && c != '_' && c != '-') + for (var i = 0; i < chars.length; ++i) { + var c = chars[i]; + if (c > maxCh || (!isLower(c) && !isDigit(c) && c != '_' && c != '-')) er("Disallowed character in CSS property"); } diff --git a/lib/ur/basis.urs b/lib/ur/basis.urs index 878f2793..c893e65d 100644 --- a/lib/ur/basis.urs +++ b/lib/ur/basis.urs @@ -79,6 +79,9 @@ val toupper : char -> char val ord : char -> int val chr : int -> char +val iscodepoint : int -> bool +val issingle : char -> bool + (** String operations *) val strlen : string -> int diff --git a/src/c/Makefile.am b/src/c/Makefile.am index 027b1458..819dd2c2 100644 --- a/src/c/Makefile.am +++ b/src/c/Makefile.am @@ -6,12 +6,12 @@ liburweb_cgi_la_SOURCES = cgi.c liburweb_fastcgi_la_SOURCES = fastcgi.c fastcgi.h liburweb_static_la_SOURCES = static.c -AM_CPPFLAGS = -I$(srcdir)/../../include/urweb $(OPENSSL_INCLUDES) +AM_CPPFLAGS = -I$(srcdir)/../../include/urweb $(OPENSSL_INCLUDES) $(ICU_INCLUDES) AM_CFLAGS = -Wall -Wunused-parameter -Werror -Wno-format-security -Wno-deprecated-declarations -U_FORTIFY_SOURCE $(PTHREAD_CFLAGS) liburweb_la_LDFLAGS = $(AM_LDFLAGS) $(OPENSSL_LDFLAGS) \ -export-symbols-regex '^(client_pruner|pthread_create_big|strcmp_nullsafe|uw_.*)' \ -version-info 1:0:0 -liburweb_la_LIBADD = $(PTHREAD_LIBS) -lm $(OPENSSL_LIBS) +liburweb_la_LIBADD = $(PTHREAD_LIBS) -lm $(OPENSSL_LIBS) $(ICU_LIBS) -licui18n -licuuc -licudata liburweb_http_la_LIBADD = liburweb.la liburweb_http_la_LDFLAGS = -export-symbols-regex '^(main|uw_.*)' \ -version-info 1:0:0 diff --git a/src/c/urweb.c b/src/c/urweb.c index e203ee37..6f36e3ed 100644 --- a/src/c/urweb.c +++ b/src/c/urweb.c @@ -20,6 +20,9 @@ #include <pthread.h> +#include <unicode/utf8.h> +#include <unicode/uchar.h> + #include "types.h" #include "uthash.h" @@ -1556,94 +1559,94 @@ const char *uw_Basis_get_settings(uw_context ctx, uw_unit u) { } } +uw_Basis_bool uw_Basis_isprint(uw_context ctx, uw_Basis_char ch); + +void jsifyChar(char**buffer_ptr, uw_context ctx, uw_Basis_char c1) { + char* buffer = *buffer_ptr; + + switch (c1) { + case '"': + strcpy(buffer, "\\\""); + buffer += 2; + break; + case '\'': + strcpy(buffer, "\\047"); + buffer += 4; + break; + case '\\': + strcpy(buffer, "\\\\"); + buffer += 2; + break; + case '<': + strcpy(buffer, "\\074"); + buffer += 4; + break; + case '&': + strcpy(buffer, "\\046"); + buffer += 4; + break; + default: + + if (uw_Basis_isprint(ctx, c1) == uw_Basis_True) + { + int offset = 0; + U8_APPEND_UNSAFE(buffer, offset, c1); + buffer += offset; + } + else { + if(65536 > c1) { + sprintf(buffer, "\\u%04x", c1); + buffer += 6; + } else { + sprintf(buffer, "\\u{%06x}", c1); + buffer += 10; + } + } + } + + + *buffer_ptr = buffer; +} + uw_Basis_string uw_Basis_jsifyString(uw_context ctx, uw_Basis_string s) { char *r, *s2; + uw_Basis_char c; - uw_check_heap(ctx, strlen(s) * 4 + 3); + uw_check_heap(ctx, strlen(s) * 10 + 3); r = s2 = ctx->heap.front; *s2++ = '"'; - for (; *s; s++) { - unsigned char c = *s; - - switch (c) { - case '"': - strcpy(s2, "\\\""); - s2 += 2; - break; - case '\'': - strcpy(s2, "\\047"); - s2 += 4; - break; - case '\\': - strcpy(s2, "\\\\"); - s2 += 2; - break; - case '<': - strcpy(s2, "\\074"); - s2 += 4; - break; - case '&': - strcpy(s2, "\\046"); - s2 += 4; - break; - default: - if (isprint((int)c) || c >= 128) - *s2++ = c; - else { - sprintf(s2, "\\%03o", c); - s2 += 4; - } + int offset = 0; + while(s[offset] != 0) + { + U8_NEXT(s, offset, -1, c); + + jsifyChar(&s2, ctx, c); } - } strcpy(s2, "\""); ctx->heap.front = s2 + 2; + return r; } +uw_Basis_int uw_Basis_ord(uw_context ctx, uw_Basis_char c); + uw_Basis_string uw_Basis_jsifyChar(uw_context ctx, uw_Basis_char c1) { - unsigned char c = c1; char *r, *s2; - uw_check_heap(ctx, 7); + uw_check_heap(ctx, 10); r = s2 = ctx->heap.front; + *s2++ = '"'; - - switch (c) { - case '"': - strcpy(s2, "\\\""); - s2 += 2; - break; - case '\'': - strcpy(s2, "\\047"); - s2 += 4; - break; - case '\\': - strcpy(s2, "\\\\"); - s2 += 2; - break; - case '<': - strcpy(s2, "\\074"); - s2 += 4; - break; - case '&': - strcpy(s2, "\\046"); - s2 += 4; - break; - default: - if (isprint((int)c) || c >= 128) - *s2++ = c; - else { - sprintf(s2, "\\%03o", (unsigned char)c); - s2 += 4; - } - } + + jsifyChar(&s2, ctx, c1); strcpy(s2, "\""); ctx->heap.front = s2 + 2; + return r; } @@ -1687,6 +1690,7 @@ uw_Basis_string uw_Basis_jsifyString_ws(uw_context ctx, uw_Basis_string s) { strcpy(s2, "\""); ctx->script.front = s2 + 1; + return r; } @@ -1971,7 +1975,7 @@ char *uw_Basis_urlifyString(uw_context ctx, uw_Basis_string s) { if (c == ' ') *p++ = '+'; - else if (isalnum(c)) + else if (U8_IS_SINGLE(c) && isalnum(c)) *p++ = c; else { sprintf(p, ".%02X", c); @@ -2063,7 +2067,7 @@ uw_unit uw_Basis_urlifyString_w(uw_context ctx, uw_Basis_string s) { if (c == ' ') uw_writec_unsafe(ctx, '+'); - else if (isalnum(c)) + else if (U8_IS_SINGLE(c) && isalnum(c)) uw_writec_unsafe(ctx, c); else { sprintf(ctx->page.front, ".%02X", c); @@ -2252,25 +2256,27 @@ uw_unit uw_Basis_htmlifyInt_w(uw_context ctx, uw_Basis_int n) { return uw_unit_v; } -char *uw_Basis_htmlifySpecialChar(uw_context ctx, unsigned char ch) { +char *uw_Basis_htmlifySpecialChar(uw_context ctx, uw_Basis_char ch) { unsigned int n = ch; int len; char *r; - uw_check_heap(ctx, INTS_MAX+3); + uw_check_heap(ctx, INTS_MAX+3 + 1); r = ctx->heap.front; - sprintf(r, "&#%u;%n", n, &len); + len = sprintf(r, "&#%u;", n); ctx->heap.front += len+1; + return r; } -uw_unit uw_Basis_htmlifySpecialChar_w(uw_context ctx, unsigned char ch) { +uw_unit uw_Basis_htmlifySpecialChar_w(uw_context ctx, uw_Basis_char ch) { unsigned int n = ch; int len; uw_check(ctx, INTS_MAX+3); - sprintf(ctx->page.front, "&#%u;%n", n, &len); + len = sprintf(ctx->page.front, "&#%u;", n); ctx->page.front += len; + return uw_unit_v; } @@ -2318,26 +2324,38 @@ uw_unit uw_Basis_jsifyInt_w(uw_context ctx, uw_Basis_int n) { char *uw_Basis_htmlifyString(uw_context ctx, const char *s) { char *r, *s2; + uw_Basis_char c1; + int oldoffset = 0, offset = 0, offset2 = 0, len = 0; + + uw_check_heap(ctx, strlen(s) * (INTS_MAX + 3) + 1); - uw_check_heap(ctx, strlen(s) * 5 + 1); - - for (r = s2 = ctx->heap.front; *s; s++) { - unsigned char c = *s; - - switch (c) { - case '<': - strcpy(s2, "<"); - s2 += 4; - break; - case '&': - strcpy(s2, "&"); - s2 += 5; - break; - default: - *s2++ = c; + r = s2 = ctx->heap.front; + + while (s[offset] != 0) { + oldoffset = offset; + U8_NEXT(s, offset, -1, c1); + + if ((offset - oldoffset == 1) && uw_Basis_isprint(ctx, c1)) { + switch (c1) { + case '<': + strcpy(s2, "<"); + s2 += 4; + break; + case '&': + strcpy(s2, "&"); + s2 += 5; + break; + default: + offset2 = 0; + U8_APPEND_UNSAFE(s2, offset2, c1); + s2 += offset2; + } + } else { + len = sprintf(s2, "&#%u;", c1); + s2 += len; } } - + *s2++ = 0; ctx->heap.front = s2; return r; @@ -2345,21 +2363,30 @@ char *uw_Basis_htmlifyString(uw_context ctx, const char *s) { uw_unit uw_Basis_htmlifyString_w(uw_context ctx, uw_Basis_string s) { uw_check(ctx, strlen(s) * 6); - - for (; *s; s++) { - unsigned char c = *s; - - switch (c) { - case '<': - uw_write_unsafe(ctx, "<"); - break; - case '&': - uw_write_unsafe(ctx, "&"); - break; - default: - uw_writec_unsafe(ctx, c); + int offset = 0, oldoffset = 0; + uw_Basis_char c1; + + while(s[offset] != 0){ + oldoffset = offset; + U8_NEXT(s, offset, -1, c1); + + if ((offset - oldoffset == 1) && uw_Basis_isprint(ctx, c1)) { + + switch (c1) { + case '<': + uw_write_unsafe(ctx, "<"); + break; + case '&': + uw_write_unsafe(ctx, "&"); + break; + default: + uw_writec_unsafe(ctx, c1); + } } - } + else { + uw_Basis_htmlifySpecialChar_w(ctx, c1); + } + } return uw_unit_v; } @@ -2421,28 +2448,34 @@ uw_unit uw_Basis_htmlifySource_w(uw_context ctx, uw_Basis_source src) { return uw_unit_v; } -uw_Basis_char uw_Basis_strsub(uw_context ctx, uw_Basis_string s, uw_Basis_int n) { +uw_Basis_char uw_Basis_strsub(uw_context ctx, uw_Basis_string s, uw_Basis_int n) { + uw_Basis_char c; + int offset = 0; + while (n >= 0) { - if (*s == 0) + + if (s[offset] == 0) uw_error(ctx, FATAL, "Out-of-bounds strsub"); + U8_NEXT(s, offset, -1, c); + if (n == 0) - return *s; + return c; --n; - ++s; } uw_error(ctx, FATAL, "Negative strsub bound"); } uw_Basis_string uw_Basis_strsuffix(uw_context ctx, uw_Basis_string s, uw_Basis_int n) { + int offset = 0; while (n >= 0) { - if (*s == 0 || n == 0) - return s; + if (s[offset] == 0 || n == 0) + return s + offset; + U8_FWD_1(s, offset, -1); --n; - ++s; } uw_error(ctx, FATAL, "Negative strsuffix bound"); @@ -2450,40 +2483,81 @@ uw_Basis_string uw_Basis_strsuffix(uw_context ctx, uw_Basis_string s, uw_Basis_i uw_Basis_int uw_Basis_strlen(uw_context ctx, uw_Basis_string s) { (void)ctx; - return strlen(s); + int offset = 0, iterations = 0; + while (s[offset] != 0) { + U8_FWD_1(s, offset, -1); + ++iterations; + } + return iterations; } uw_Basis_bool uw_Basis_strlenGe(uw_context ctx, uw_Basis_string s, uw_Basis_int n) { (void)ctx; - + int offset = 0; while (n > 0) { - if (*s == 0) + if (s[offset] == 0) return uw_Basis_False; - + + U8_FWD_1(s, offset, -1); --n; - ++s; } return uw_Basis_True; } +int aux_strchr(uw_Basis_string s, uw_Basis_char ch, int* o_offset) { + int u8idx = 0, offset = 0, offsetpr = 0; + uw_Basis_char c; + + while (s[offset] != 0) { + U8_NEXT(s, offset, -1, c); + if (c == ch) { + *o_offset = offsetpr; + return u8idx; + } + + offsetpr = offset; + ++u8idx; + } + + *o_offset = -1; + return -1; +} + uw_Basis_string uw_Basis_strchr(uw_context ctx, uw_Basis_string s, uw_Basis_char ch) { (void)ctx; - return strchr(s, ch); + int offset = -1; + if (aux_strchr(s, ch, &offset) > -1) { + return s + offset; + } + return NULL; } uw_Basis_int uw_Basis_strcspn(uw_context ctx, uw_Basis_string s, uw_Basis_string chs) { (void)ctx; - return strcspn(s, chs); + int offset = 0, u8idx = 0, offsetChs = 0; + uw_Basis_char c; + + while (s[offset] != 0) { + U8_NEXT(s, offset, -1, c); + if (aux_strchr(chs, c, &offsetChs) > -1) { + return u8idx; + } + ++u8idx; + } + + return u8idx; } uw_Basis_int *uw_Basis_strindex(uw_context ctx, uw_Basis_string s, uw_Basis_char ch) { - uw_Basis_string r = strchr(s, ch); - if (r == NULL) + (void)ctx; + int offset = -1; + int r = aux_strchr(s, ch, &offset); + if (r == -1) return NULL; else { uw_Basis_int *nr = uw_malloc(ctx, sizeof(uw_Basis_int)); - *nr = r - s; + *nr = r; return nr; } } @@ -2494,13 +2568,19 @@ uw_Basis_int *uw_Basis_strsindex(uw_context ctx, const char *haystack, const cha return NULL; else { uw_Basis_int *nr = uw_malloc(ctx, sizeof(uw_Basis_int)); - *nr = r - haystack; + int src = r - haystack, offset = 0, utf8idx = 0; + while (offset < src) { + U8_FWD_1(haystack, offset, -1); + ++utf8idx; + } + + *nr = utf8idx; return nr; } } uw_Basis_string uw_Basis_strcat(uw_context ctx, uw_Basis_string s1, uw_Basis_string s2) { - int len = uw_Basis_strlen(ctx, s1) + uw_Basis_strlen(ctx, s2) + 1; + int len = strlen(s1) + strlen(s2) + 1; char *s; uw_check_heap(ctx, len); @@ -2515,8 +2595,8 @@ uw_Basis_string uw_Basis_strcat(uw_context ctx, uw_Basis_string s1, uw_Basis_str } uw_Basis_string uw_Basis_substring(uw_context ctx, uw_Basis_string s, uw_Basis_int start, uw_Basis_int len) { - size_t full_len = uw_Basis_strlen(ctx, s); - + int full_len = uw_Basis_strlen(ctx, s); + if (start < 0) uw_error(ctx, FATAL, "substring: Negative start index"); if (len < 0) @@ -2524,32 +2604,41 @@ uw_Basis_string uw_Basis_substring(uw_context ctx, uw_Basis_string s, uw_Basis_i if (start + len > full_len) uw_error(ctx, FATAL, "substring: Start index plus length is too large"); - if (start + len == full_len) - return &s[start]; - else { - uw_Basis_string r = uw_malloc(ctx, len+1); - memcpy(r, s+start, len); - r[len] = 0; + int offset = 0; + U8_FWD_N(s, offset, -1, start); + + if (start + len == full_len) { + return s + offset; + } else { + int end = offset; + U8_FWD_N(s, end, -1, len); + + int actual_len = end - offset; + + uw_Basis_string r = uw_malloc(ctx, actual_len + 1); + memcpy(r, s + offset, actual_len); + r[actual_len] = 0; return r; } - } uw_Basis_string uw_Basis_str1(uw_context ctx, uw_Basis_char ch) { char *r; - - uw_check_heap(ctx, 2); + int req = U8_LENGTH(ch); + int offset = 0; + + uw_check_heap(ctx, req + 1); r = ctx->heap.front; - r[0] = ch; - r[1] = 0; - ctx->heap.front += 2; + U8_APPEND_UNSAFE(r, offset, ch); + r[req] = 0; - return r; + ctx->heap.front += req + 1; + return r; } uw_Basis_string uw_strdup(uw_context ctx, uw_Basis_string s1) { - int len = uw_Basis_strlen(ctx, s1) + 1; + int len = strlen(s1) + 1; char *s; uw_check_heap(ctx, len); @@ -2676,7 +2765,6 @@ uw_Basis_string uw_Basis_sqlifyString(uw_context ctx, uw_Basis_string s) { uw_Basis_string uw_Basis_sqlifyChar(uw_context ctx, uw_Basis_char c) { char *r, *s2; - uw_check_heap(ctx, 5 + uw_Estrings + strlen(uw_sqlsuffixChar)); r = s2 = ctx->heap.front; @@ -2934,10 +3022,7 @@ uw_Basis_string uw_Basis_floatToString(uw_context ctx, uw_Basis_float n) { } uw_Basis_string uw_Basis_charToString(uw_context ctx, uw_Basis_char ch) { - char *r = uw_malloc(ctx, 2); - r[0] = ch; - r[1] = 0; - return r; + return uw_Basis_str1(ctx, ch); } uw_Basis_string uw_Basis_boolToString(uw_context ctx, uw_Basis_bool b) { @@ -2997,11 +3082,12 @@ uw_Basis_char *uw_Basis_stringToChar(uw_context ctx, uw_Basis_string s) { uw_Basis_char *r = uw_malloc(ctx, 1); r[0] = 0; return r; - } else if (s[1] != 0) + } else if (uw_Basis_strlenGe(ctx, s, 2) == uw_Basis_True) return NULL; else { uw_Basis_char *r = uw_malloc(ctx, 1); - r[0] = s[0]; + int offset = 0; + U8_NEXT(s, offset, -1, *r); return r; } } @@ -3126,10 +3212,14 @@ uw_Basis_float uw_Basis_stringToFloat_error(uw_context ctx, uw_Basis_string s) { uw_Basis_char uw_Basis_stringToChar_error(uw_context ctx, uw_Basis_string s) { if (s[0] == 0) return 0; - else if (s[1] != 0) + else if (uw_Basis_strlenGe(ctx, s, 2) == uw_Basis_True) uw_error(ctx, FATAL, "Can't parse char: %s", uw_Basis_htmlifyString(ctx, s)); - else - return s[0]; + else { + uw_Basis_char c; + int offset = 0; + U8_NEXT(s, offset, -1, c); + return c; + } } uw_Basis_bool uw_Basis_stringToBool_error(uw_context ctx, uw_Basis_string s) { @@ -4328,82 +4418,98 @@ void uw_set_global(uw_context ctx, char *name, void *data, void (*free)(void*)) uw_Basis_bool uw_Basis_isalnum(uw_context ctx, uw_Basis_char c) { (void)ctx; - return !!isalnum((int)c); + return !!u_hasBinaryProperty(c, UCHAR_POSIX_ALNUM); } uw_Basis_bool uw_Basis_isalpha(uw_context ctx, uw_Basis_char c) { (void)ctx; - return !!isalpha((int)c); + return !!u_hasBinaryProperty(c, UCHAR_ALPHABETIC); } uw_Basis_bool uw_Basis_isblank(uw_context ctx, uw_Basis_char c) { (void)ctx; - return !!isblank((int)c); + return !!u_hasBinaryProperty(c, UCHAR_POSIX_BLANK); } uw_Basis_bool uw_Basis_iscntrl(uw_context ctx, uw_Basis_char c) { (void)ctx; - return !!iscntrl((int)c); + return !!(u_charType(c)==U_CONTROL_CHAR); } uw_Basis_bool uw_Basis_isdigit(uw_context ctx, uw_Basis_char c) { (void)ctx; - return !!isdigit((int)c); + return !!u_isdigit(c); } uw_Basis_bool uw_Basis_isgraph(uw_context ctx, uw_Basis_char c) { (void)ctx; - return !!isgraph((int)c); + return !!u_hasBinaryProperty(c, UCHAR_POSIX_GRAPH); } uw_Basis_bool uw_Basis_islower(uw_context ctx, uw_Basis_char c) { (void)ctx; - return !!islower((int)c); + return !!u_hasBinaryProperty(c, UCHAR_LOWERCASE); } uw_Basis_bool uw_Basis_isprint(uw_context ctx, uw_Basis_char c) { (void)ctx; - return !!isprint((int)c); + return !!u_hasBinaryProperty(c, UCHAR_POSIX_PRINT); } uw_Basis_bool uw_Basis_ispunct(uw_context ctx, uw_Basis_char c) { (void)ctx; - return !!ispunct((int)c); + return !!u_ispunct(c); } uw_Basis_bool uw_Basis_isspace(uw_context ctx, uw_Basis_char c) { (void)ctx; - return !!isspace((int)c); + return !!u_hasBinaryProperty(c, UCHAR_WHITE_SPACE); } uw_Basis_bool uw_Basis_isupper(uw_context ctx, uw_Basis_char c) { (void)ctx; - return !!isupper((int)c); + return !!u_hasBinaryProperty(c, UCHAR_UPPERCASE); } uw_Basis_bool uw_Basis_isxdigit(uw_context ctx, uw_Basis_char c) { (void)ctx; - return !!isxdigit((int)c); + return !!(c <= 0x7f && u_isxdigit(c)); } uw_Basis_char uw_Basis_tolower(uw_context ctx, uw_Basis_char c) { (void)ctx; - return tolower((int)c); + return u_tolower(c); } uw_Basis_char uw_Basis_toupper(uw_context ctx, uw_Basis_char c) { (void)ctx; - return toupper((int)c); + return u_toupper(c); } uw_Basis_int uw_Basis_ord(uw_context ctx, uw_Basis_char c) { (void)ctx; - return (unsigned char)c; + return (uw_Basis_int)c; +} + +uw_Basis_bool uw_Basis_iscodepoint (uw_context ctx, uw_Basis_int n) { + (void)ctx; + return !!(n <= 0x10FFFF); +} + +uw_Basis_bool uw_Basis_issingle (uw_context ctx, uw_Basis_char c) { + (void)ctx; + return !!(c < 128); } uw_Basis_char uw_Basis_chr(uw_context ctx, uw_Basis_int n) { (void)ctx; - return n; + uw_Basis_char ch = (uw_Basis_char)n; + + if (n > 0x10FFFF) { + uw_error(ctx, FATAL, "The integer %lld is not a valid char codepoint", n); + } + + return ch; } uw_Basis_string uw_Basis_currentUrl(uw_context ctx) { @@ -4657,7 +4763,7 @@ uw_Basis_string uw_Basis_atom(uw_context ctx, uw_Basis_string s) { for (p = s; *p; ++p) { char c = *p; - if (!isalnum((int)c) && c != '+' && c != '-' && c != '.' && c != '%' && c != '#') + if (!U8_IS_SINGLE(c) || (!isalnum((int)c) && c != '+' && c != '-' && c != '.' && c != '%' && c != '#')) uw_error(ctx, FATAL, "Disallowed character in CSS atom"); } @@ -4669,8 +4775,8 @@ uw_Basis_string uw_Basis_css_url(uw_context ctx, uw_Basis_string s) { for (p = s; *p; ++p) { char c = *p; - if (!isalnum((int)c) && c != ':' && c != '/' && c != '.' && c != '_' && c != '+' - && c != '-' && c != '%' && c != '?' && c != '&' && c != '=' && c != '#') + if (!U8_IS_SINGLE(c) || (!isalnum((int)c) && c != ':' && c != '/' && c != '.' && c != '_' && c != '+' + && c != '-' && c != '%' && c != '?' && c != '&' && c != '=' && c != '#')) uw_error(ctx, FATAL, "Disallowed character in CSS URL"); } @@ -4683,12 +4789,12 @@ uw_Basis_string uw_Basis_property(uw_context ctx, uw_Basis_string s) { if (!*s) uw_error(ctx, FATAL, "Empty CSS property"); - if (!islower((int)s[0]) && s[0] != '_') + if (!U8_IS_SINGLE(s[0]) || (!islower((int)s[0]) && s[0] != '_')) uw_error(ctx, FATAL, "Bad initial character in CSS property"); for (p = s; *p; ++p) { char c = *p; - if (!islower((int)c) && !isdigit((int)c) && c != '_' && c != '-') + if (!U8_IS_SINGLE(c) || (!islower((int)c) && !isdigit((int)c) && c != '_' && c != '-')) uw_error(ctx, FATAL, "Disallowed character in CSS property"); } @@ -4739,9 +4845,9 @@ uw_Basis_postField *uw_Basis_firstFormField(uw_context ctx, uw_Basis_string s) { uw_Basis_string uw_Basis_blessData(uw_context ctx, uw_Basis_string s) { char *p = s; - + for (; *p; ++p) - if (!isalnum(*p) && *p != '-' && *p != '_') + if (!U8_IS_SINGLE(*p) || (!isalnum(*p) && *p != '-' && *p != '_')) uw_error(ctx, FATAL, "Illegal HTML5 data-* attribute: %s", s); return s; @@ -5064,7 +5170,7 @@ void uw_Sqlcache_flush(uw_context ctx, uw_Sqlcache_Cache *cache, char **keys) { pthread_rwlock_unlock(&cache->lockIn); } -int strcmp_nullsafe(const char *str1, const char *str2) { +int strcmp_nullsafe(const char *str1, const char *str2) { if (str1) return strcmp(str1, str2); else @@ -5073,7 +5179,7 @@ int strcmp_nullsafe(const char *str1, const char *str2) { static int is_valid_hash(uw_Basis_string hash) { for (; *hash; ++hash) - if (!isxdigit(*hash)) + if (!U8_IS_SINGLE(*hash) || !isxdigit(*hash)) return 0; return 1; diff --git a/src/compiler.sml b/src/compiler.sml index e7de4d82..868dd628 100644 --- a/src/compiler.sml +++ b/src/compiler.sml @@ -1593,9 +1593,9 @@ fun compileC {cname, oname, ename, libs, profile, debug, linker, link = link'} = val proto = Settings.currentProtocol () val lib = if Settings.getBootLinking () then - !Settings.configLib ^ "/" ^ #linkStatic proto ^ " " ^ !Settings.configLib ^ "/liburweb.a" + !Settings.configLib ^ "/" ^ #linkStatic proto ^ " " ^ !Settings.configLib ^ "/liburweb.a " ^ !Settings.configIcuLibs ^ " -licui18n -licuuc -licudata" else if Settings.getStaticLinking () then - " -static " ^ !Settings.configLib ^ "/" ^ #linkStatic proto ^ " " ^ !Settings.configLib ^ "/liburweb.a" + " -static " ^ !Settings.configLib ^ "/" ^ #linkStatic proto ^ " " ^ !Settings.configLib ^ "/liburweb.a " ^ !Settings.configIcuLibs ^ " -licui18n -licuuc -licudata" else "-L" ^ !Settings.configLib ^ " " ^ #linkDynamic proto ^ " -lurweb" @@ -1606,6 +1606,7 @@ fun compileC {cname, oname, ename, libs, profile, debug, linker, link = link'} = val compile = (Settings.getCCompiler ()) ^ " " ^ Config.ccArgs ^ " " ^ Config.pthreadCflags ^ " -Wimplicit -Werror -Wno-unused-value" ^ opt ^ " -I " ^ !Settings.configInclude + ^ " " ^ !Settings.configIcuIncludes ^ " " ^ #compile proto ^ " -c " ^ escapeFilename cname ^ " -o " ^ escapeFilename oname diff --git a/src/config.sig b/src/config.sig index a3ad7d76..be72a8cc 100644 --- a/src/config.sig +++ b/src/config.sig @@ -20,4 +20,7 @@ signature CONFIG = sig val pthreadCflags : string val pthreadLibs : string + + val icuIncludes : string + val icuLibs : string end diff --git a/src/config.sml.in b/src/config.sml.in index ebcdb7b6..2d12e28d 100644 --- a/src/config.sml.in +++ b/src/config.sml.in @@ -28,6 +28,9 @@ val pgheader = "@PGHEADER@" val msheader = "@MSHEADER@" val sqheader = "@SQHEADER@" +val icuIncludes = "@ICU_INCLUDES@" +val icuLibs = "@ICU_LIBS@" + val versionNumber = "@VERSION@" val versionString = "The Ur/Web compiler, version " ^ versionNumber diff --git a/src/settings.sig b/src/settings.sig index f94525bb..a6a9c5fc 100644 --- a/src/settings.sig +++ b/src/settings.sig @@ -37,6 +37,8 @@ signature SETTINGS = sig val configSrcLib : string ref val configInclude : string ref val configSitelisp : string ref + val configIcuIncludes : string ref + val configIcuLibs : string ref val libUr : unit -> string val libC : unit -> string diff --git a/src/settings.sml b/src/settings.sml index 6499da67..f42df135 100644 --- a/src/settings.sml +++ b/src/settings.sml @@ -32,7 +32,8 @@ val configLib = ref Config.lib val configSrcLib = ref Config.srclib val configInclude = ref Config.includ val configSitelisp = ref Config.sitelisp - +val configIcuIncludes = ref Config.icuIncludes +val configIcuLibs = ref Config.icuLibs val configCCompiler = ref Config.ccompiler fun getCCompiler () = !configCCompiler diff --git a/tests/Makefile b/tests/Makefile index ecf5557b..03e37e4b 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -28,3 +28,5 @@ simple:: ./driver.sh fact ./driver.sh filter ./driver.sh jsbspace + ./driver.sh utf8 + diff --git a/tests/utf8.py b/tests/utf8.py new file mode 100644 index 00000000..6036fa12 --- /dev/null +++ b/tests/utf8.py @@ -0,0 +1,174 @@ +import unittest +import base + +class Suite(base.Base): + + def no_falses(self, name): + self.start('Utf8/' + name) + + elems = self.driver.find_elements_by_xpath('//pre') + + self.assertNotEqual(0, len(elems)) + for e in elems: + self.assertEqual("True", e.text) + + def test_1(self): + """Test case: substring (1)""" + self.no_falses('substrings') + + def test_2(self): + """Test case: strlen (2)""" + self.no_falses('strlens') + + def test_3(self): + """Test case: strlenGe (3)""" + self.no_falses('strlenGens') + + def test_4(self): + """Test case: strcat (4)""" + self.no_falses('strcats') + + def test_5(self): + """Test case: strsub (5)""" + self.no_falses('strsubs') + + def test_6(self): + """Test case: strsuffix (6)""" + self.no_falses('strsuffixs') + + def test_7(self): + """Test case: strchr (7)""" + self.no_falses('strchrs') + + def test_8(self): + """Test case: strindex (8)""" + self.no_falses('strindexs') + + def test_9(self): + """Test case: strindex (9)""" + self.no_falses('strsindexs') + + def test_10(self): + """Test case: strcspn (10)""" + self.no_falses('strcspns') + + def test_11(self): + """Test case: str1 (11)""" + self.no_falses('str1s') + + def test_12(self): + """Test case: isalnum (12)""" + self.no_falses('isalnums') + + def test_13(self): + """Test case: isalpha (13)""" + self.no_falses('isalphas') + + def test_14(self): + """Test case: isblank (14)""" + self.no_falses('isblanks') + + def test_15(self): + """Test case: iscntrl (15)""" + self.no_falses('iscntrls') + + def test_16(self): + """Test case: isdigit (16)""" + self.no_falses('isdigits') + + def test_17(self): + """Test case: isgraph (17)""" + self.no_falses('isgraphs') + + def test_18(self): + """Test case: islower (18)""" + self.no_falses('islowers') + + def test_19(self): + """Test case: isprint (19)""" + self.no_falses('isprints') + + def test_20(self): + """Test case: ispunct (20)""" + self.no_falses('ispuncts') + + def test_21(self): + """Test case: isspace (21)""" + self.no_falses('isspaces') + + def test_22(self): + """Test case: isupper (22)""" + self.no_falses('isuppers') + + def test_23(self): + """Test case: isxdigit (23)""" + self.no_falses('isxdigits') + + def test_24(self): + """Test case: toupper (24)""" + self.no_falses('touppers') + + def test_25(self): + """Test case: ord (25)""" + self.no_falses('ord_and_chrs') + + def test_26 (self): + """Test case: test_db (26) """ + self.no_falses('test_db') + + def full_test (self, name): + + gap = 1000 + i = 0 + while (i + gap < 130000): + self.start('Utf8/' + name + '/' + str(i) + '/' + str(i + gap)) + errors = self.body_text() + self.assertEqual("", errors, errors) + i = i + gap + + + def test_89 (self): + """Test case: ftTolower """ + self.full_test("ftTolower") + + def test_90 (self): + """Test case: ftToupper """ + self.full_test("ftToupper") + + def test_91 (self): + """Test case: ftIsalpha """ + self.full_test("ftIsalpha") + + def test_92 (self): + """Test case: ftIsdigit """ + self.full_test("ftIsdigit") + + def test_93 (self): + """Test case: ftIsalnum """ + self.full_test("ftIsalnum") + + def test_94 (self): + """Test case: ftIsspace """ + self.full_test("ftIsspace") + + def test_95 (self): + """Test case: ftIsblank """ + self.full_test("ftIsblank") + + def test_96 (self): + """Test case: ftIsprint """ + self.full_test("ftIsprint") + + def test_97 (self): + """Test case: ftIsxdigit """ + self.full_test("ftIsxdigit") + + def test_98 (self): + """Test case: ftIsupper """ + self.full_test("ftIsupper") + + def test_99 (self): + """Test case: ftIslower """ + self.full_test("ftIslower") + ''' + ''' diff --git a/tests/utf8.ur b/tests/utf8.ur new file mode 100644 index 00000000..4a89c22b --- /dev/null +++ b/tests/utf8.ur @@ -0,0 +1,794 @@ + +fun from_m_upto_n f m n = + if m < n then + <xml> + { f m } + { from_m_upto_n f (m + 1) n } + </xml> + else + <xml></xml> + +fun test_fn_both_sides [a ::: Type] (_ : eq a) (_ : show a) (f : unit -> a) (expected : a) (testname : string) : xbody = +<xml> + <p>Server side test: {[testname]}</p> + <pre>{[show (f () = expected)]}</pre> + <active code={return <xml><p>Client side test: {[testname]}</p><pre>{[show (f () = expected)]}</pre></xml>}> +</active> +</xml> + +fun test_fn_sside [a ::: Type] (_ : eq a) (_ : show a) (f : unit -> a) (expected : a) (testname : string) : xbody = + <xml> + <p>Server side test: {[testname]}</p> + <pre>{[show (f () = expected)]}</pre> + </xml> + +fun test_fn_cside [a ::: Type] (_ : eq a) (_ : show a) (f : unit -> a) (expected : a) (testname : string) : xbody = + <xml> + <active code={return <xml><p>Client side test: {[testname]}</p><pre>{[show (f () = expected)]}</pre></xml>}> + </active> + </xml> + + +fun test_fn_cside_ch (f : unit -> char) (expected : char) (testname : string) : xbody = + <xml> + <active code={let + val computed = f () + val msgErr = "Expected (S) " ^ (show expected) ^ " [" ^ (show (ord expected)) ^ "] but is (C) " ^ + (show computed) ^ "[" ^ (show (ord computed)) ^ "]." + in + if computed = expected then + return <xml></xml> + else + return <xml><p>ERROR {[testname]}: {[msgErr]}</p></xml> + end}> + </active> + </xml> + +fun test_fn_cside_b (f : unit -> bool) (expected : bool) (testname : string) : xbody = + <xml> + <active code={let + val computed = f () + val msgErr = "Expected (S) " ^ (show expected) ^ " but is (C) " ^ + (show computed) ^ "." + in + if computed = expected then + return <xml></xml> + else + return <xml><p>ERROR {[testname]}: {[msgErr]}</p></xml> + end}> + </active> +</xml> + + +fun highencode () : transaction page = + return <xml> + <body> + {test_fn_cside (fn _ => strlen "ππππ") (strlen "ππππ") "high encode - strlen 1"} + {test_fn_cside (fn _ => strlen "πππ") (strlen "πππ") "high encode - strlen 2"} + {test_fn_cside (fn _ => strlen "ππ") (strlen "ππ") "high encode - strlen 3"} + {test_fn_cside (fn _ => strlen "π") (strlen "π") "high encode - strlen 4"} + + {test_fn_cside (fn _ => substring "ππππ" 1 3) (substring "ππππ" 1 3) "high encode - substring 1"} + {test_fn_cside (fn _ => substring "ππππ" 2 2) (substring "ππππ" 2 2) "high encode - substring 2"} + {test_fn_cside (fn _ => substring "ππππ" 3 1) (substring "ππππ" 3 1) "high encode - substring 3"} + + {test_fn_cside (fn _ => strlen (substring "ππππ" 1 3)) (strlen (substring "ππππ" 1 3)) "high encode - strlen of substring 1"} + {test_fn_cside (fn _ => strlen (substring "ππππ" 2 2)) (strlen (substring "ππππ" 2 2)) "high encode - strlen of substring 2"} + {test_fn_cside (fn _ => strlen (substring "ππππ" 3 1)) (strlen (substring "ππππ" 3 1)) "high encode - strlen of substring 3"} + + {test_fn_cside (fn _ => strsub "ππππ" 0) (strsub "ππππ" 0) "high encode - strsub 1"} + {test_fn_cside (fn _ => strsub "ππππ" 1) (strsub "ππππ" 1) "high encode - strsub 2"} + {test_fn_cside (fn _ => strsub "ππππ" 2) (strsub "ππππ" 2) "high encode - strsub 3"} + {test_fn_cside (fn _ => strsub "ππππ" 3) (strsub "ππππ" 3) "high encode - strsub 4"} + + {test_fn_cside (fn _ => strsuffix "ππππ" 0) (strsuffix "ππππ" 0) "high encode - strsuffix 1"} + {test_fn_cside (fn _ => strsuffix "ππππ" 1) (strsuffix "ππππ" 1) "high encode - strsuffix 2"} + {test_fn_cside (fn _ => strsuffix "ππππ" 2) (strsuffix "ππππ" 2) "high encode - strsuffix 3"} + {test_fn_cside (fn _ => strsuffix "ππππ" 3) (strsuffix "ππππ" 3) "high encode - strsuffix 4"} + + {test_fn_cside (fn _ => strchr "ππππ" #"c") (strchr "ππππ" #"c") "high encode - strchr 1"} + {test_fn_cside (fn _ => strchr "ππππ" (strsub "π" 0)) (strchr "ππππ" (strsub "π" 0)) "high encode - strchr 2"} + {test_fn_cside (fn _ => strchr "ππππ" (strsub "π" 0)) (strchr "ππππ" (strsub "π" 0)) "high encode - strchr 3"} + {test_fn_cside (fn _ => strchr "ππππ" (strsub "π" 0)) (strchr "ππππ" (strsub "π" 0)) "high encode - strchr 4"} + {test_fn_cside (fn _ => strchr "ππππ" (strsub "π" 0)) (strchr "ππππ" (strsub "π" 0)) "high encode - strchr 5"} + + {test_fn_cside (fn _ => strindex "ππππ" #"c") (strindex "ππππ" #"c") "high encode - strindex 1"} + {test_fn_cside (fn _ => strindex "ππππ" (strsub "π" 0)) (strindex "ππππ" (strsub "π" 0)) "high encode - strindex 2"} + {test_fn_cside (fn _ => strindex "ππππ" (strsub "π" 0)) (strindex "ππππ" (strsub "π" 0)) "high encode - strindex 3"} + {test_fn_cside (fn _ => strindex "ππππ" (strsub "π" 0)) (strindex "ππππ" (strsub "π" 0)) "high encode - strindex 4"} + {test_fn_cside (fn _ => strindex "ππππ" (strsub "π" 0)) (strindex "ππππ" (strsub "π" 0)) "high encode - strindex 5"} + + {test_fn_cside (fn _ => strsindex "ππππ" "") (strsindex "ππππ" "") "high encode - strsindex 1"} + {test_fn_cside (fn _ => strsindex "ππππ" "ππππ") (strsindex "ππππ" "ππππ") "high encode - strsindex 2"} + {test_fn_cside (fn _ => strsindex "ππππ" "πππc") (strsindex "ππππ" "πππc") "high encode - strsindex 3"} + {test_fn_cside (fn _ => strsindex "ππππ" "πππ") (strsindex "ππππ" "πππ") "high encode - strsindex 4"} + {test_fn_cside (fn _ => strsindex "ππππ" "ππc") (strsindex "ππππ" "ππc") "high encode - strsindex 5"} + {test_fn_cside (fn _ => strsindex "ππππ" "ππ") (strsindex "ππππ" "ππ") "high encode - strsindex 6"} + {test_fn_cside (fn _ => strsindex "ππππ" "πc") (strsindex "ππππ" "πc") "high encode - strsindex 7"} + {test_fn_cside (fn _ => strsindex "ππππ" "π") (strsindex "ππππ" "π") "high encode - strsindex 8"} + {test_fn_cside (fn _ => strsindex "ππππ" "c") (strsindex "ππππ" "c") "high encode - strsindex 9"} + + {test_fn_cside (fn _ => strcspn "ππππ" "") (strcspn "ππππ" "") "high encode - strcspn 1"} + {test_fn_cside (fn _ => strcspn "ππππ" "ππππ") (strcspn "ππππ" "ππππ") "high encode - strcspn 2"} + {test_fn_cside (fn _ => strcspn "ππππ" "π") (strcspn "ππππ" "π") "high encode - strcspn 3"} + {test_fn_cside (fn _ => strcspn "ππππ" "πππ") (strcspn "ππππ" "πππ") "high encode - strcspn 4"} + {test_fn_cside (fn _ => strcspn "ππππ" "ππ") (strcspn "ππππ" "ππ") "high encode - strcspn 5"} + {test_fn_cside (fn _ => strcspn "ππππ" "π") (strcspn "ππππ" "π") "high encode - strcspn 6"} + + {test_fn_cside (fn _ => ord (strsub "ππππ" 0)) (ord (strsub "ππππ" 0)) "high encode - ord 1"} + {test_fn_cside (fn _ => ord (strsub "ππππ" 1)) (ord (strsub "ππππ" 1)) "high encode - ord 2"} + {test_fn_cside (fn _ => ord (strsub "ππππ" 2)) (ord (strsub "ππππ" 2)) "high encode - ord 3"} + {test_fn_cside (fn _ => ord (strsub "ππππ" 3)) (ord (strsub "ππππ" 3)) "high encode - ord 4"} + + {test_fn_cside (fn _ => show (strsub "ππππ" 0)) (show (strsub "ππππ" 0)) "high encode - show 1"} + {test_fn_cside (fn _ => show (strsub "ππππ" 1)) (show (strsub "ππππ" 1)) "high encode - show 2"} + {test_fn_cside (fn _ => show (strsub "ππππ" 2)) (show (strsub "ππππ" 2)) "high encode - show 3"} + {test_fn_cside (fn _ => show (strsub "ππππ" 3)) (show (strsub "ππππ" 3)) "high encode - show 4"} + + </body> + </xml> + +fun substrings () : transaction page = + return <xml> + <body> + {test_fn_both_sides (fn _ => substring "abc" 0 3) "abc" "substrings 1"} + {test_fn_both_sides (fn _ => substring "abc" 1 2) "bc" "substrings 2"} + {test_fn_both_sides (fn _ => substring "abc" 2 1) "c" "substrings 3"} + {test_fn_both_sides (fn _ => substring "Γ‘bΓ³" 0 3) "Γ‘bΓ³" "substrings 4"} + {test_fn_both_sides (fn _ => substring "Γ‘bΓ³" 1 2) "bΓ³" "substrings 5"} + {test_fn_both_sides (fn _ => substring "Γ‘bΓ³" 2 1) "Γ³" "substrings 6"} + {test_fn_both_sides (fn _ => substring "Γ‘bΓ³" 0 2) "Γ‘b" "substrings 7"} + {test_fn_both_sides (fn _ => substring "Γ‘bΓ³" 0 1) "Γ‘" "substrings 8"} + {test_fn_both_sides (fn _ => substring "" 0 0) "" "substrings 9"} + </body> + </xml> + + +fun strlens () : transaction page = return <xml> + <body> + {test_fn_both_sides (fn _ => strlen "abc") 3 "strlen 1"} + {test_fn_both_sides (fn _ => strlen "Γ§bc") 3 "strlen 2"} + {test_fn_both_sides (fn _ => strlen "çãc") 3 "strlen 3"} + {test_fn_both_sides (fn _ => strlen "çãó") 3 "strlen 4"} + {test_fn_both_sides (fn _ => strlen "Γ§") 1 "strlen 5"} + {test_fn_both_sides (fn _ => strlen "c") 1 "strlen 6"} + {test_fn_both_sides (fn _ => strlen "") 0 "strlen 7"} + {test_fn_both_sides (fn _ => strlen "γ") 1 "strlen 8"} + {test_fn_both_sides (fn _ => strlen "ζΌ’") 1 "strlen 9"} + {test_fn_both_sides (fn _ => strlen "γ«") 1 "strlen 10"} + {test_fn_both_sides (fn _ => strlen "ΩΨΈΩΩΩΨ©") 6 "strlen 11"} + {test_fn_both_sides (fn _ => strlen "ε½ζΈ") 2 "strlen 12"} + {test_fn_both_sides (fn _ => strlen "Π€ΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»ΡΠ½ΠΎΠ΅") 14 "strlen 13"} + </body> + </xml> + +fun strlenGens () : transaction page = return <xml> + <body> + {test_fn_both_sides (fn _ => strlenGe "" 1) False "strlenGe 1"} + {test_fn_both_sides (fn _ => strlenGe "" 0) True "strlenGe 2"} + {test_fn_both_sides (fn _ => strlenGe "aba" 4) False "strlenGe 3"} + {test_fn_both_sides (fn _ => strlenGe "aba" 3) True "strlenGe 4"} + {test_fn_both_sides (fn _ => strlenGe "aba" 2) True "strlenGe 5"} + {test_fn_both_sides (fn _ => strlenGe "à çÑ" 4) False "strlenGe 6"} + {test_fn_both_sides (fn _ => strlenGe "à çÑ" 3) True "strlenGe 7"} + {test_fn_both_sides (fn _ => strlenGe "à çÑ" 2) True "strlenGe 8"} + </body> + </xml> + +type clen = { S : string, L : int } + +val clen_eq : eq clen = mkEq (fn a b => + a.S = b.S && a.L = b.L) + +val clen_show : show clen = mkShow (fn a => + "{S = " ^ a.S ^ ", L = " ^ (show a.L) ^ "}") + +fun strcats () : transaction page = + let + fun test_cat_and_len n a b expS expL = + test_fn_both_sides (fn _ => let val c = strcat a b in {S = c, L = strlen c} end) {S=expS, L=expL} ("strcat " ^ (show n)) + in + return <xml> + <body> + {test_cat_and_len 1 "" "" "" 0} + {test_cat_and_len 2 "aa" "bb" "aabb" 4} + {test_cat_and_len 3 "" "bb" "bb" 2} + {test_cat_and_len 4 "aa" "" "aa" 2} + {test_cat_and_len 5 "Γ Γ " "ÑÑ" "à à ÑÑ" 4} + {test_cat_and_len 6 "" "ÑÑ" "ÑÑ" 2} + {test_cat_and_len 7 "Γ Γ " "" "Γ Γ " 2} + {test_cat_and_len 8 "ε½ζΈ" "ãã" "ε½ζΈΓ£Γ£" 4} + {test_cat_and_len 9 "Γ§" "Γ£" "çã" 2} + {test_cat_and_len 10 (show (strsub "Γ§" 0)) (show (strsub "Γ£" 0)) "çã" 2} + {test_cat_and_len 11 (show (chr 231)) (show (chr 227)) "çã" 2} + </body> + </xml> +end + +fun strsubs () : transaction page = + return <xml> + <body> + {test_fn_both_sides (fn _ => strsub "abΓ Γ§" 0) #"a" "strsub 1"} + {test_fn_both_sides (fn _ => strsub "abΓ Γ§" 1) #"b" "strsub 2"} + {test_fn_both_sides (fn _ => strsub "Γ b" 0) (strsub "Γ " 0) "strsub 3"} + {test_fn_both_sides (fn _ => strsub "abΓ Γ§" 2) (strsub "Γ " 0) "strsub 4"} + {test_fn_both_sides (fn _ => strsub "abΓ Γ§" 3) (strsub "Γ§" 0) "strsub 5"} + </body> + </xml> + +fun strsuffixs () : transaction page = + return <xml> + <body> + {test_fn_both_sides (fn _ => strsuffix "abΓ Γ§" 0) "abΓ Γ§" "strsuffix 1"} + {test_fn_both_sides (fn _ => strsuffix "abΓ Γ§" 1) "bΓ Γ§" "strsuffix 2"} + {test_fn_both_sides (fn _ => strsuffix "abΓ Γ§" 2) "Γ Γ§" "strsuffix 3"} + {test_fn_both_sides (fn _ => strsuffix "abΓ Γ§" 3) "Γ§" "strsuffix 4"} + </body> + </xml> + +fun strchrs () : transaction page = + return <xml> + <body> + {test_fn_both_sides (fn _ => strchr "abΓ Γ§" #"c") None "strchr 1"} + {test_fn_both_sides (fn _ => strchr "abΓ Γ§" #"a") (Some "abΓ Γ§") "strchr 2"} + {test_fn_both_sides (fn _ => strchr "abΓ Γ§" #"b") (Some "bΓ Γ§") "strchr 3"} + {test_fn_both_sides (fn _ => strchr "abΓ Γ§" (strsub "Γ " 0)) (Some "Γ Γ§") "strchr 4"} + {test_fn_both_sides (fn _ => strchr "abΓ Γ§" (strsub "Γ§" 0)) (Some "Γ§") "strchr 5"} + </body> + </xml> + +fun strindexs () : transaction page = + return <xml> + <body> + {test_fn_both_sides (fn _ => strindex "abΓ Γ§" #"c") None "strindex 1"} + {test_fn_both_sides (fn _ => strindex "abΓ Γ§" #"a") (Some 0) "strindex 2"} + {test_fn_both_sides (fn _ => strindex "abΓ Γ§" #"b") (Some 1) "strindex 3"} + {test_fn_both_sides (fn _ => strindex "abΓ Γ§" (strsub "Γ " 0)) (Some 2) "strindex 4"} + {test_fn_both_sides (fn _ => strindex "abΓ Γ§" (strsub "Γ§" 0)) (Some 3) "strindex 5"} + </body> + </xml> + +fun strsindexs () : transaction page = + return <xml> + <body> + {test_fn_both_sides (fn _ => strsindex "abΓ Γ§" "") (Some 0) "strsindex 1"} + {test_fn_both_sides (fn _ => strsindex "abΓ Γ§" "abΓ Γ§") (Some 0) "strsindex 2"} + {test_fn_both_sides (fn _ => strsindex "abΓ Γ§" "abΓ c") None "strsindex 3"} + {test_fn_both_sides (fn _ => strsindex "abΓ Γ§" "bΓ Γ§") (Some 1) "strsindex 4"} + {test_fn_both_sides (fn _ => strsindex "abΓ Γ§" "bΓ c") None "strsindex 5"} + {test_fn_both_sides (fn _ => strsindex "abΓ Γ§" "Γ Γ§") (Some 2) "strsindex 6"} + {test_fn_both_sides (fn _ => strsindex "abΓ Γ§" "Γ c") None "strsindex 7"} + {test_fn_both_sides (fn _ => strsindex "abΓ Γ§" "Γ§") (Some 3) "strsindex 8"} + {test_fn_both_sides (fn _ => strsindex "abΓ Γ§" "c") None "strsindex 9"} + </body> + </xml> + +fun strcspns () : transaction page = + return <xml> + <body> + {test_fn_both_sides (fn _ => strcspn "abΓ Γ§" "") 4 "strcspn 1"} + {test_fn_both_sides (fn _ => strcspn "abΓ Γ§" "abΓ Γ§") 0 "strcspn 2"} + {test_fn_both_sides (fn _ => strcspn "abΓ Γ§" "a") 0 "strcspn 3"} + {test_fn_both_sides (fn _ => strcspn "abΓ Γ§" "bΓ Γ§") 1 "strcspn 4"} + {test_fn_both_sides (fn _ => strcspn "abΓ Γ§" "Γ Γ§") 2 "strcspn 5"} + {test_fn_both_sides (fn _ => strcspn "abΓ Γ§" "Γ§") 3 "strcspn 6"} + </body> + </xml> + +fun str1s () : transaction page = return <xml> + <body> + {test_fn_both_sides (fn _ => str1 #"a") "a" "str1 1"} + {test_fn_both_sides (fn _ => str1 (strsub "Γ " 0)) "Γ " "str1 2"} + {test_fn_both_sides (fn _ => str1 (strsub "aΓ‘" 1)) "Γ‘" "str1 3"} + </body> + </xml> + +fun isalnums () : transaction page = return <xml> + <body> + {test_fn_both_sides (fn _ => isalnum #"a") True "isalnum 1"} + {test_fn_both_sides (fn _ => isalnum #"a") True "isalnum 2"} + {test_fn_both_sides (fn _ => isalnum (strsub "Γ " 0)) True "isalnum 3"} + {test_fn_both_sides (fn _ => isalnum #"A") True "isalnum 4"} + {test_fn_both_sides (fn _ => isalnum (strsub "Γ" 0)) True "isalnum 5"} + {test_fn_both_sides (fn _ => isalnum #"1") True "isalnum 6"} + {test_fn_both_sides (fn _ => not (isalnum #"!")) True "isalnum 7"} + {test_fn_both_sides (fn _ => not (isalnum #"#")) True "isalnum 8"} + {test_fn_both_sides (fn _ => not (isalnum #" ")) True "isalnum 9"} + </body> +</xml> + +fun isalphas () : transaction page = return <xml> + <body> + {test_fn_both_sides (fn _ => isalpha #"a") True "isalpha 1"} + {test_fn_both_sides (fn _ => isalpha (strsub "Γ " 0)) True "isalpha 2"} + {test_fn_both_sides (fn _ => isalpha #"A") True "isalpha 3"} + {test_fn_both_sides (fn _ => isalpha (strsub "Γ" 0)) True "isalpha 4"} + {test_fn_both_sides (fn _ => not (isalpha #"1")) True "isalpha 5"} + {test_fn_both_sides (fn _ => not (isalpha #"!")) True "isalpha 6"} + {test_fn_both_sides (fn _ => not (isalpha #"#")) True "isalpha 7"} + {test_fn_both_sides (fn _ => not (isalpha #" ")) True "isalpha 8"} + </body> +</xml> + +fun isblanks () : transaction page = + return <xml> + <body> + {test_fn_both_sides (fn _ => not (isblank #"a")) True "isblank 1"} + {test_fn_both_sides (fn _ => not (isblank (strsub "Γ " 0))) True "isblank 2"} + {test_fn_both_sides (fn _ => not (isblank #"A")) True "isblank 3"} + {test_fn_both_sides (fn _ => not (isblank (strsub "Γ" 0))) True "isblank 4"} + {test_fn_both_sides (fn _ => not (isblank #"1")) True "isblank 5"} + {test_fn_both_sides (fn _ => not (isblank #"!")) True "isblank 6"} + {test_fn_both_sides (fn _ => not (isblank #"#")) True "isblank 7"} + {test_fn_both_sides (fn _ => isblank #" ") True "isblank 8"} + {test_fn_both_sides (fn _ => isblank #"\t") True "isblank 9"} + {test_fn_both_sides (fn _ => not (isblank #"\n")) True "isblank 10"} + </body> + </xml> + +fun iscntrls () : transaction page = + return <xml> + <body> + {test_fn_sside (fn _ => not (iscntrl #"a")) True "iscntrl 1"} + {test_fn_sside (fn _ => not (iscntrl (strsub "Γ " 0))) True "iscntrl 2"} + {test_fn_sside (fn _ => not (iscntrl #"A")) True "iscntrl 3"} + {test_fn_sside (fn _ => not (iscntrl (strsub "Γ" 0))) True "iscntrl 4"} + {test_fn_sside (fn _ => not (iscntrl #"1")) True "iscntrl 5"} + {test_fn_sside (fn _ => not (iscntrl #"!")) True "iscntrl 6"} + {test_fn_sside (fn _ => not (iscntrl #"#")) True "iscntrl 7"} + {test_fn_sside (fn _ => not (iscntrl #" ")) True "iscntrl 8"} + {test_fn_sside (fn _ => iscntrl #"\t") True "iscntrl 9"} + {test_fn_sside (fn _ => iscntrl #"\n") True "iscntrl 10"} + </body> + </xml> + +fun isdigits () : transaction page = + return <xml> + <body> + {test_fn_both_sides (fn _ => not (isdigit #"a")) True "isdigit 1"} + {test_fn_both_sides (fn _ => not (isdigit (strsub "Γ " 0))) True "isdigit 2"} + {test_fn_both_sides (fn _ => not (isdigit #"A")) True "isdigit 3"} + {test_fn_both_sides (fn _ => not (isdigit (strsub "Γ" 0))) True "isdigit 4"} + {test_fn_both_sides (fn _ => isdigit #"1") True "isdigit 5"} + {test_fn_both_sides (fn _ => not (isdigit #"!")) True "isdigit 6"} + {test_fn_both_sides (fn _ => not (isdigit #"#")) True "isdigit 7"} + {test_fn_both_sides (fn _ => not (isdigit #" ")) True "isdigit 8"} + {test_fn_both_sides (fn _ => not (isdigit #"\t")) True "isdigit 9"} + {test_fn_both_sides (fn _ => not (isdigit #"\n")) True "isdigit 10"} + </body> + </xml> + +fun isgraphs () : transaction page = + return <xml> + <body> + {test_fn_sside (fn _ => isgraph #"a") True "isgraph 1"} + {test_fn_sside (fn _ => isgraph (strsub "Γ " 0)) True "isgraph 2"} + {test_fn_sside (fn _ => isgraph #"A") True "isgraph 3"} + {test_fn_sside (fn _ => isgraph (strsub "Γ" 0)) True "isgraph 4"} + {test_fn_sside (fn _ => isgraph #"1") True "isgraph 5"} + {test_fn_sside (fn _ => isgraph #"!") True "isgraph 6"} + {test_fn_sside (fn _ => isgraph #"#") True "isgraph 7"} + {test_fn_sside (fn _ => not (isgraph #" ")) True "isgraph 8"} + {test_fn_sside (fn _ => not (isgraph #"\t")) True "isgraph 9"} + {test_fn_sside (fn _ => not (isdigit #"\n")) True "isgraph 10"} + </body> + </xml> + +fun islowers () : transaction page = + return <xml> + <body> + {test_fn_both_sides (fn _ => islower #"a") True "islower 1"} + {test_fn_both_sides (fn _ => islower (strsub "Γ " 0)) True "islower 2"} + {test_fn_both_sides (fn _ => not (islower #"A")) True "islower 3"} + {test_fn_both_sides (fn _ => not (islower (strsub "Γ" 0))) True "islower 4"} + {test_fn_both_sides (fn _ => not (islower #"1")) True "islower 5"} + {test_fn_both_sides (fn _ => not (islower #"!")) True "islower 6"} + {test_fn_both_sides (fn _ => not (islower #"#")) True "islower 7"} + {test_fn_both_sides (fn _ => not (islower #" ")) True "islower 8"} + {test_fn_both_sides (fn _ => not (islower #"\t")) True "islower 9"} + {test_fn_both_sides (fn _ => not (islower #"\n")) True "islower 10"} + </body> + </xml> + +fun isprints () : transaction page = + return <xml> + <body> + {test_fn_both_sides (fn _ => isprint #"a") True "isprint 1"} + {test_fn_both_sides (fn _ => isprint (strsub "Γ " 0)) True "isprint 2"} + {test_fn_both_sides (fn _ => isprint #"A") True "isprint 3"} + {test_fn_both_sides (fn _ => isprint (strsub "Γ" 0)) True "isprint 4"} + {test_fn_both_sides (fn _ => isprint #"1") True "isprint 5"} + {test_fn_both_sides (fn _ => isprint #"!") True "isprint 6"} + {test_fn_both_sides (fn _ => isprint #"#") True "isprint 7"} + {test_fn_both_sides (fn _ => isprint #" ") True "isprint 8"} + {test_fn_both_sides (fn _ => not (isprint #"\t")) True "isprint 9"} + {test_fn_both_sides (fn _ => not (isprint #"\n")) True "isprint 10"} + </body> + </xml> + +fun ispuncts () : transaction page = + return <xml> + <body> + {test_fn_sside (fn _ => not (ispunct #"a")) True "ispunct 1"} + {test_fn_sside (fn _ => not (ispunct (strsub "Γ " 0))) True "ispunct 2"} + {test_fn_sside (fn _ => not (ispunct #"A")) True "ispunct 3"} + {test_fn_sside (fn _ => not (ispunct (strsub "Γ" 0))) True "ispunct 4"} + {test_fn_sside (fn _ => not (ispunct #"1")) True "ispunct 5"} + {test_fn_sside (fn _ => ispunct #"!") True "ispunct 6"} + {test_fn_sside (fn _ => ispunct #"#") True "ispunct 7"} + {test_fn_sside (fn _ => not (ispunct #" ")) True "ispunct 8"} + {test_fn_sside (fn _ => not (isprint #"\t")) True "ispunct 9"} + {test_fn_sside (fn _ => not (isprint #"\n")) True "ispunct 10"} + </body> + </xml> + +fun isspaces () : transaction page = + return <xml> + <body> + {test_fn_both_sides (fn _ => not (isspace #"a")) True "isspace 1"} + {test_fn_both_sides (fn _ => not (isspace (strsub "Γ " 0))) True "isspace 2"} + {test_fn_both_sides (fn _ => not (isspace #"A")) True "isspace 3"} + {test_fn_both_sides (fn _ => not (isspace (strsub "Γ" 0))) True "isspace 4"} + {test_fn_both_sides (fn _ => not (isspace #"1")) True "isspace 5"} + {test_fn_both_sides (fn _ => not (isspace #"!")) True "isspace 6"} + {test_fn_both_sides (fn _ => not (isspace #"#")) True "isspace 7"} + {test_fn_both_sides (fn _ => isspace #" ") True "isspace 8"} + {test_fn_both_sides (fn _ => isspace #"\t") True "isspace 9"} + {test_fn_both_sides (fn _ => isspace #"\n") True "isspace 10"} + </body> + </xml> + +fun isuppers () : transaction page = + return <xml> + <body> + {test_fn_both_sides (fn _ => not (isupper #"a")) True "isupper 1"} + {test_fn_both_sides (fn _ => not (isupper (strsub "Γ " 0))) True "isupper 2"} + {test_fn_both_sides (fn _ => isupper #"A") True "isupper 3"} + {test_fn_both_sides (fn _ => isupper (strsub "Γ" 0)) True "isupper 4"} + {test_fn_both_sides (fn _ => not (isupper #"1")) True "isupper 5"} + {test_fn_both_sides (fn _ => not (isupper #"!")) True "isupper 6"} + {test_fn_both_sides (fn _ => not (isupper #"#")) True "isupper 7"} + {test_fn_both_sides (fn _ => not (isupper #" ")) True "isupper 8"} + {test_fn_both_sides (fn _ => not (isupper #"\t")) True "isupper 9"} + {test_fn_both_sides (fn _ => not (isupper #"\n")) True "isupper 10"} + </body> + </xml> + +fun isxdigits () : transaction page = + return <xml> + <body> + {test_fn_both_sides (fn _ => isxdigit #"a") True "isxdigit 1"} + {test_fn_both_sides (fn _ => not (isxdigit (strsub "Γ " 0))) True "isxdigit 2"} + {test_fn_both_sides (fn _ => isxdigit #"A") True "isxdigit 3"} + {test_fn_both_sides (fn _ => not (isxdigit (strsub "Γ" 0))) True "isxdigit 4"} + {test_fn_both_sides (fn _ => isxdigit #"1") True "isxdigit 5"} + {test_fn_both_sides (fn _ => not (isxdigit #"!")) True "isxdigit 6"} + {test_fn_both_sides (fn _ => not (isxdigit #"#")) True "isxdigit 7"} + {test_fn_both_sides (fn _ => not (isxdigit #" ")) True "isxdigit 8"} + {test_fn_both_sides (fn _ => not (isxdigit #"\t")) True "isxdigit 9"} + {test_fn_both_sides (fn _ => not (isxdigit #"\n")) True "isxdigit 10"} + </body> + </xml> + +fun tolowers () : transaction page = + let + fun lower_of a _ = + tolower a + in + return <xml> + <body> + {test_fn_both_sides (lower_of #"A") #"a" "tolower 1"} + {test_fn_both_sides (lower_of #"a") #"a" "tolower 2"} + {test_fn_both_sides (lower_of (strsub "Γ‘" 0)) (strsub "Γ‘" 0) "tolower 3"} + {test_fn_both_sides (lower_of (strsub "Γ" 0)) (strsub "Γ‘" 0) "tolower 4"} + {test_fn_both_sides (lower_of #"1") #"1" "tolower 5"} + {test_fn_cside (lower_of (strsub "Γ" 0)) (lower_of (strsub "Γ" 0) ()) "tolower 6"} + </body> + </xml> + end + +fun touppers () : transaction page = + let + fun upper_of a _ = + toupper a + in + return <xml> + <body> + {test_fn_both_sides (upper_of #"A") #"A" "toupper 1"} + {test_fn_both_sides (upper_of #"a") #"A" "toupper 2"} + {test_fn_both_sides (upper_of (strsub "Γ‘" 0)) (strsub "Γ" 0) "toupper 3"} + {test_fn_both_sides (upper_of (strsub "Γ" 0)) (strsub "Γ" 0) "toupper 4"} + {test_fn_both_sides (upper_of #"1") #"1" "toupper 5"} + + {test_fn_cside (upper_of (strsub "Γ" 0)) (upper_of (strsub "Γ" 0) ()) "toupper 6"} + </body> + </xml> + end + +fun ord_and_chrs () : transaction page = + return <xml> + <body> + {test_fn_both_sides (fn _ => chr (ord #"A")) #"A" "ord => chr 1"} + {test_fn_both_sides (fn _ => chr (ord #"a")) #"a" "ord => chr 2"} + {test_fn_both_sides (fn _ => chr (ord (strsub "Γ‘" 0))) (strsub "Γ‘" 0) "ord => chr 3"} + {test_fn_both_sides (fn _ => chr (ord (strsub "Γ" 0))) (strsub "Γ" 0) "ord => chr 4"} + {test_fn_both_sides (fn _ => chr (ord #"1")) #"1" "ord => chr 5"} + {test_fn_both_sides (fn _ => chr (ord #"\n")) #"\n" "ord => chr 6"} + {test_fn_both_sides (fn _ => chr (ord (strsub "γ" 0))) (strsub "γ" 0) "ord => chr 7"} + {test_fn_both_sides (fn _ => chr (ord (strsub "ζΌ’" 0))) (strsub "ζΌ’" 0) "ord => chr 8"} + {test_fn_both_sides (fn _ => chr (ord (strsub "γ«" 0))) (strsub "γ«" 0) "ord => chr 9"} + </body> + </xml> + +fun test_ords () : transaction page = + let + fun ord_of c _ = + ord c + in + return <xml> + <body> + {test_fn_cside (ord_of (strsub "a" 0)) (ord_of (strsub "a" 0) ()) "test ord 1"} + {test_fn_cside (ord_of (strsub "Γ‘" 0)) (ord_of (strsub "Γ‘" 0) ()) "test ord 2"} + {test_fn_cside (ord_of (strsub "5" 0)) (ord_of (strsub "5" 0) ()) "test ord 3"} + {test_fn_cside (ord_of (strsub "γ" 0)) (ord_of (strsub "γ" 0) ()) "test ord 4"} + {test_fn_cside (ord_of (strsub "ζΌ’" 0)) (ord_of (strsub "ζΌ’" 0) ()) "test ord 5"} + {test_fn_cside (ord_of (strsub "γ«" 0)) (ord_of (strsub "γ«" 0) ()) "test ord 6"} + </body> + </xml> + end + +table t : { Id : int, Text : string } + +fun test_db () : transaction page = + let + val s1 = "abc" + val s2 = "çãó" + val s3 = "γ" + val s4 = "ζΌ’" + val s5 = "γ«" + val s6 = "ΩΨΈΩΩΩΨ©" + + fun test_str_and_len n c expS expL = + test_fn_both_sides (fn _ => {S = c, L = strlen c}) {S=expS, L=expL} ("test_db " ^ (show n)) + + in + dml (INSERT INTO t (Id, Text) VALUES({[1]}, {[s1]})); + t1 <- oneRow (SELECT t.Text FROM t WHERE t.Id = 1); + + dml (INSERT INTO t (Id, Text) VALUES({[2]}, {[s2]})); + t2 <- oneRow (SELECT t.Text FROM t WHERE t.Id = 2); + + dml (INSERT INTO t (Id, Text) VALUES({[3]}, {[s3]})); + t3 <- oneRow (SELECT t.Text FROM t WHERE t.Id = 3); + + dml (INSERT INTO t (Id, Text) VALUES({[4]}, {[s4]})); + t4 <- oneRow (SELECT t.Text FROM t WHERE t.Id = 4); + + dml (INSERT INTO t (Id, Text) VALUES({[5]}, {[s5]})); + t5 <- oneRow (SELECT t.Text FROM t WHERE t.Id = 5); + + dml (INSERT INTO t (Id, Text) VALUES({[6]}, {[s6]})); + t6 <- oneRow (SELECT t.Text FROM t WHERE t.Id = 6); + + return <xml> + <body> + {test_str_and_len 1 t1.T.Text s1 (strlen s1)} + {test_str_and_len 2 t2.T.Text s2 (strlen s2)} + {test_str_and_len 3 t3.T.Text s3 (strlen s3)} + {test_str_and_len 4 t4.T.Text s4 (strlen s4)} + {test_str_and_len 5 t5.T.Text s5 (strlen s5)} + {test_str_and_len 6 t6.T.Text s6 (strlen s6)} + </body> + </xml> + end + +and ftTolower (minCh : int) (maxCh : int) : transaction page = + let + fun test_chr (n : int) : xbody = + if iscodepoint n then + test_fn_cside_ch (fn _ => tolower (chr n)) (tolower (chr n)) + ("test chr " ^ (show n) ^ " : " ^ (show (chr n))) + else + <xml></xml> + in + return <xml> + <body> + { from_m_upto_n (fn n => test_chr n) minCh maxCh } + </body> + </xml> + end + +and ftToupper (minCh : int) (maxCh : int) : transaction page = + let + fun test_chr (n : int) : xbody = + if iscodepoint n then + test_fn_cside_ch (fn _ => toupper (chr n)) (toupper (chr n)) + ("test chr " ^ (show n) ^ " : " ^ (show (chr n))) + else + <xml></xml> + in + return <xml> + <body> + { from_m_upto_n (fn n => test_chr n) minCh maxCh } + </body> + </xml> + end + +and ftIsalpha (minCh : int) (maxCh : int) : transaction page = + let + fun test_chr (n : int) : xbody = + if iscodepoint n then + test_fn_cside_b (fn _ => isalpha (chr n)) (isalpha (chr n)) + ("test chr " ^ (show n) ^ " : " ^ (show (chr n))) + else + <xml></xml> + in + return <xml> + <body> + { from_m_upto_n (fn n => test_chr n) minCh maxCh } + </body> + </xml> + end + +and ftIsdigit (minCh : int) (maxCh : int) : transaction page = + let + fun test_chr (n : int) : xbody = + if iscodepoint n then + test_fn_cside_b (fn _ => isdigit (chr n)) (isdigit (chr n)) + ("test chr " ^ (show n) ^ " : " ^ (show (chr n))) + else + <xml></xml> + in + return <xml> + <body> + { from_m_upto_n (fn n => test_chr n) minCh maxCh } + </body> + </xml> + end + +and ftIsalnum (minCh : int) (maxCh : int) : transaction page = + let + fun test_chr (n : int) : xbody = + if iscodepoint n then + test_fn_cside_b (fn _ => isalnum (chr n)) (isalnum (chr n)) + ("test chr " ^ (show n) ^ " : " ^ (show (chr n))) + else + <xml></xml> + in + return <xml> + <body> + { from_m_upto_n (fn n => test_chr n) minCh maxCh } + </body> + </xml> + end + +and ftIsspace (minCh : int) (maxCh : int) : transaction page = + let + fun test_chr (n : int) : xbody = + if iscodepoint n then + test_fn_cside_b (fn _ => isspace (chr n)) (isspace (chr n)) + ("test chr " ^ (show n) ^ " : " ^ (show (chr n))) + else + <xml></xml> + in + return <xml> + <body> + { from_m_upto_n (fn n => test_chr n) minCh maxCh } + </body> + </xml> + end + +and ftIsblank (minCh : int) (maxCh : int) : transaction page = + let + fun test_chr (n : int) : xbody = + if iscodepoint n then + test_fn_cside_b (fn _ => isblank (chr n)) (isblank (chr n)) + ("test chr " ^ (show n) ^ " : " ^ (show (chr n))) + else + <xml></xml> + in + return <xml> + <body> + { from_m_upto_n (fn n => test_chr n) minCh maxCh } + </body> + </xml> + end + +and ftIsprint (minCh : int) (maxCh : int) : transaction page = + let + fun test_chr (n : int) : xbody = + if iscodepoint n then + test_fn_cside_b (fn _ => isprint (chr n)) (isprint (chr n)) + ("test chr " ^ (show n) ^ " : " ^ (show (chr n))) + else + <xml></xml> + in + return <xml> + <body> + { from_m_upto_n (fn n => test_chr n) minCh maxCh } + </body> + </xml> + end + +and ftIsxdigit (minCh : int) (maxCh : int) : transaction page = + let + fun test_chr (n : int) : xbody = + if iscodepoint n then + test_fn_cside_b (fn _ => isxdigit (chr n)) (isxdigit (chr n)) + ("test chr " ^ (show n) ^ " : " ^ (show (chr n))) + else + <xml></xml> + in + return <xml> + <body> + { from_m_upto_n (fn n => test_chr n) minCh maxCh } + </body> + </xml> + end + +and ftIsupper (minCh : int) (maxCh : int) : transaction page = + let + fun test_chr (n : int) : xbody = + if iscodepoint n then + test_fn_cside_b (fn _ => isupper (chr n)) (isupper (chr n)) + ("test chr " ^ (show n) ^ " : " ^ (show (chr n))) + else + <xml></xml> + in + return <xml> + <body> + { from_m_upto_n (fn n => test_chr n) minCh maxCh } + </body> + </xml> + end + +and ftIslower (minCh : int) (maxCh : int) : transaction page = + let + fun test_chr (n : int) : xbody = + if iscodepoint n then + test_fn_cside_b (fn _ => islower (chr n)) (islower (chr n)) + ("test chr " ^ (show n) ^ " : " ^ (show (chr n))) + else + <xml></xml> + in + return <xml> + <body> + { from_m_upto_n (fn n => test_chr n) minCh maxCh } + </body> + </xml> + end + +fun index () : transaction page = + return <xml> + <body> + <a link={substrings ()}>substrings</a> + <a link={strlens ()}>strlens</a> + <a link={strlenGens ()}>strlenGens</a> + <a link={strcats ()}>strcats</a> + <a link={strsubs ()}>strsubs</a> + <a link={strsuffixs ()}>strsuffixs</a> + <a link={strchrs ()}>strchrs</a> + <a link={strindexs ()}>strindexs</a> + <a link={strsindexs ()}>strsindexs</a> + <a link={strcspns ()}>strcspns</a> + <a link={str1s ()}>str1s</a> + <a link={isalnums ()}>isalnums</a> + <a link={isalphas ()}>isalphas</a> + <a link={isblanks ()}>isblanks</a> + <a link={iscntrls ()}>iscntrls</a> + <a link={isdigits ()}>isdigits</a> + <a link={isgraphs ()}>isgraphs</a> + <a link={islowers ()}>islowers</a> + <a link={isprints ()}>isprints</a> + <a link={ispuncts ()}>ispuncts</a> + <a link={isspaces ()}>isspaces</a> + <a link={isuppers ()}>isuppers</a> + <a link={isxdigits ()}>isxdigits</a> + <a link={tolowers ()}>tolowers</a> + <a link={touppers ()}>touppers</a> + <a link={ord_and_chrs ()}>ord_and_chrs</a> + <a link={test_ords ()}>test ord</a> + <a link={highencode ()}>highencode</a> + <a link={test_db ()}>test_db</a> + </body> + </xml> diff --git a/tests/utf8.urp b/tests/utf8.urp new file mode 100644 index 00000000..25288aa8 --- /dev/null +++ b/tests/utf8.urp @@ -0,0 +1,6 @@ +database dbname=utf8 +sql utf8.sql +safeGet Utf8/test_db + +$/option +utf8
\ No newline at end of file |