summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml7
-rw-r--r--configure.ac2
-rw-r--r--include/urweb/types_cpp.h3
-rw-r--r--include/urweb/urweb_cpp.h5
-rw-r--r--lib/js/urweb.js2994
-rw-r--r--lib/ur/basis.urs3
-rw-r--r--src/c/Makefile.am4
-rw-r--r--src/c/urweb.c452
-rw-r--r--src/compiler.sml5
-rw-r--r--src/config.sig3
-rw-r--r--src/config.sml.in3
-rw-r--r--src/settings.sig2
-rw-r--r--src/settings.sml3
-rw-r--r--tests/Makefile2
-rw-r--r--tests/utf8.py174
-rw-r--r--tests/utf8.ur794
-rw-r--r--tests/utf8.urp6
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, "&lt;");
- s2 += 4;
- break;
- case '&':
- strcpy(s2, "&amp;");
- 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, "&lt;");
+ s2 += 4;
+ break;
+ case '&':
+ strcpy(s2, "&amp;");
+ 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, "&lt;");
- break;
- case '&':
- uw_write_unsafe(ctx, "&amp;");
- 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, "&lt;");
+ break;
+ case '&':
+ uw_write_unsafe(ctx, "&amp;");
+ 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