From c2a217f9121dd865122bc6150c53e77bd662050d Mon Sep 17 00:00:00 2001 From: fab Date: Sat, 3 Nov 2018 20:09:20 +0000 Subject: utf-8 aware functions for basis. unit-testing. --- src/c/urweb.c | 197 ++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 131 insertions(+), 66 deletions(-) (limited to 'src/c/urweb.c') diff --git a/src/c/urweb.c b/src/c/urweb.c index 2e3e18bc..69c3da94 100644 --- a/src/c/urweb.c +++ b/src/c/urweb.c @@ -20,6 +20,9 @@ #include +#include +#include + #include "types.h" #include "uthash.h" @@ -2421,28 +2424,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 +2459,80 @@ 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; + uw_Basis_char c; + + while (s[offset] != 0) { + U8_NEXT(s, offset, -1, c); + if (c == ch) { + *o_offset = offset; + return u8idx; + } + + ++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 +2543,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 +2570,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 +2579,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 +2740,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 +2997,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 +3057,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 +3187,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 +4393,82 @@ 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 !!u_hasBinaryProperty(c, UCHAR_POSIX_XDIGIT); } 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_char uw_Basis_chr(uw_context ctx, uw_Basis_int n) { (void)ctx; - return n; + return (uw_Basis_char)n; } uw_Basis_string uw_Basis_currentUrl(uw_context ctx) { @@ -4657,7 +4722,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,7 +4734,7 @@ 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 != '+' + 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"); } @@ -4688,7 +4753,7 @@ uw_Basis_string uw_Basis_property(uw_context ctx, uw_Basis_string s) { 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"); } @@ -5064,7 +5129,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 +5138,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; -- cgit v1.2.3 From f6d40570a8859260571f0b904ba329a1c4d1046c Mon Sep 17 00:00:00 2001 From: fab Date: Mon, 19 Nov 2018 20:33:20 +0000 Subject: several fixes on unit tests and implementation --- lib/js/urweb.js | 6 +- src/c/urweb.c | 22 ++- tests/utf8.py | 344 +------------------------------- tests/utf8.ur | 605 ++++++++++++++++++++++++++++++-------------------------- tests/utf8.urp | 1 + 5 files changed, 350 insertions(+), 628 deletions(-) (limited to 'src/c/urweb.c') diff --git a/lib/js/urweb.js b/lib/js/urweb.js index f81f05e3..de1a2ad0 100644 --- a/lib/js/urweb.js +++ b/lib/js/urweb.js @@ -27,8 +27,8 @@ 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 isLower(c) { return c.toLowerCase() == c && c != c.toUpperCase(); } +function isUpper(c) { return c.toUpperCase() == c && c != c.toLowerCase(); } function isAlpha(c) { return isLower(c) || isUpper(c); } function isDigit(c) { return c >= '0' && c <= '9'; } function isAlnum(c) { return isAlpha(c) || isDigit(c); } @@ -36,7 +36,7 @@ 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 isPrint(c) { return ord(c) > 31 && ord(c) != 127; } function toLower(c) { return c.toLowerCase(); } function toUpper(c) { return c.toUpperCase(); } diff --git a/src/c/urweb.c b/src/c/urweb.c index 69c3da94..be65afcc 100644 --- a/src/c/urweb.c +++ b/src/c/urweb.c @@ -1606,8 +1606,9 @@ uw_Basis_string uw_Basis_jsifyString(uw_context ctx, uw_Basis_string s) { return r; } +uw_Basis_bool uw_Basis_isprint(uw_context ctx, uw_Basis_char ch); + 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); @@ -1615,7 +1616,7 @@ uw_Basis_string uw_Basis_jsifyChar(uw_context ctx, uw_Basis_char c1) { r = s2 = ctx->heap.front; *s2++ = '"'; - switch (c) { + switch (c1) { case '"': strcpy(s2, "\\\""); s2 += 2; @@ -1637,10 +1638,16 @@ uw_Basis_string uw_Basis_jsifyChar(uw_context ctx, uw_Basis_char c1) { s2 += 4; break; default: - if (isprint((int)c) || c >= 128) - *s2++ = c; + + if (uw_Basis_isprint(ctx, c1) == uw_Basis_True) + { + int offset = 0; + U8_APPEND_UNSAFE(s2, offset, c1); + s2 += offset; + } else { - sprintf(s2, "\\%03o", (unsigned char)c); + assert(0777 >= c1); + sprintf(s2, "\\%03o", (unsigned char)c1); s2 += 4; } } @@ -2482,16 +2489,17 @@ uw_Basis_bool uw_Basis_strlenGe(uw_context ctx, uw_Basis_string s, uw_Basis_int } int aux_strchr(uw_Basis_string s, uw_Basis_char ch, int* o_offset) { - int u8idx = 0, offset = 0; + 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 = offset; + *o_offset = offsetpr; return u8idx; } + offsetpr = offset; ++u8idx; } diff --git a/tests/utf8.py b/tests/utf8.py index ff9b737a..440bc82a 100644 --- a/tests/utf8.py +++ b/tests/utf8.py @@ -5,445 +5,103 @@ class Suite(base.Base): def test_1(self): """Test case: substring (1)""" self.start('Utf8/substrings') - - pre = self.xpath('pre[1]') - self.assertEqual('abc', pre.text) - - pre = self.xpath('pre[2]') - self.assertEqual('bc', pre.text) - - pre = self.xpath('pre[3]') - self.assertEqual('c', pre.text) - - pre = self.xpath('pre[4]') - self.assertEqual('ábó', pre.text) - - pre = self.xpath('pre[5]') - self.assertEqual('bó', pre.text) - - pre = self.xpath('pre[6]') - self.assertEqual('ó', pre.text) - - pre = self.xpath('pre[7]') - self.assertEqual('çãó', pre.text) - - pre = self.xpath('pre[8]') - self.assertEqual('ãó', pre.text) - - pre = self.xpath('pre[9]') - self.assertEqual('ó', pre.text) - - pre = self.xpath('pre[10]') - self.assertEqual('', pre.text) - - pre = self.xpath('pre[11]') - self.assertEqual('', pre.text) - def test_2(self): """Test case: strlen (2)""" self.start('Utf8/strlens') - - pre = self.xpath('pre[1]') - self.assertEqual('3', pre.text) - - pre = self.xpath('pre[2]') - self.assertEqual('3', pre.text) - - pre = self.xpath('pre[3]') - self.assertEqual('3', pre.text) - - pre = self.xpath('pre[4]') - self.assertEqual('3', pre.text) - - pre = self.xpath('pre[5]') - self.assertEqual('1', pre.text) - - pre = self.xpath('pre[6]') - self.assertEqual('1', pre.text) - - pre = self.xpath('pre[7]') - self.assertEqual('0', pre.text) - - pre = self.xpath('pre[8]') - self.assertEqual('1', pre.text) - - pre = self.xpath('pre[9]') - self.assertEqual('1', pre.text) - - pre = self.xpath('pre[10]') - self.assertEqual('1', pre.text) - - pre = self.xpath('pre[11]') - self.assertEqual('6', pre.text) - - pre = self.xpath('pre[12]') - self.assertEqual('2', pre.text) - - pre = self.xpath('pre[13]') - self.assertEqual('14', pre.text) - def test_3(self): """Test case: strlenGe (3)""" self.start('Utf8/strlenGens') - - pre = self.xpath('pre[1]') - self.assertEqual('False', pre.text) - - pre = self.xpath('pre[2]') - self.assertEqual('True', pre.text) - - pre = self.xpath('pre[3]') - self.assertEqual('False', pre.text) - - pre = self.xpath('pre[4]') - self.assertEqual('True', pre.text) - - pre = self.xpath('pre[5]') - self.assertEqual('True', pre.text) - - pre = self.xpath('pre[6]') - self.assertEqual('False', pre.text) - - pre = self.xpath('pre[7]') - self.assertEqual('True', pre.text) - - pre = self.xpath('pre[8]') - self.assertEqual('True', pre.text) def test_4(self): """Test case: strcat (4)""" self.start('Utf8/strcats') - - pre = self.xpath('pre[1]') - self.assertEqual('', pre.text) - - pre = self.xpath('pre[2]') - self.assertEqual('0', pre.text) - - pre = self.xpath('pre[3]') - self.assertEqual('aabb', pre.text) - - pre = self.xpath('pre[4]') - self.assertEqual('4', pre.text) - - pre = self.xpath('pre[5]') - self.assertEqual('bb', pre.text) - - pre = self.xpath('pre[6]') - self.assertEqual('2', pre.text) - - pre = self.xpath('pre[7]') - self.assertEqual('aa', pre.text) - - pre = self.xpath('pre[8]') - self.assertEqual('2', pre.text) - - pre = self.xpath('pre[9]') - self.assertEqual('ààáá', pre.text) - - pre = self.xpath('pre[10]') - self.assertEqual('4', pre.text) - - pre = self.xpath('pre[11]') - self.assertEqual('áá', pre.text) - - pre = self.xpath('pre[12]') - self.assertEqual('2', pre.text) - - pre = self.xpath('pre[13]') - self.assertEqual('àà', pre.text) - - pre = self.xpath('pre[14]') - self.assertEqual('2', pre.text) def test_5(self): """Test case: strsub (5)""" self.start('Utf8/strsubs') - pre = self.xpath('pre[1]') - self.assertEqual('a', pre.text) - - pre = self.xpath('pre[2]') - self.assertEqual('b', pre.text) - - pre = self.xpath('pre[3]') - self.assertEqual('à', pre.text) - - pre = self.xpath('pre[4]') - self.assertEqual('ç', pre.text) - def test_6(self): """Test case: strsuffix (6)""" self.start('Utf8/strsuffixs') - pre = self.xpath('pre[1]') - self.assertEqual('abàç', pre.text) - - pre = self.xpath('pre[2]') - self.assertEqual('bàç', pre.text) - - pre = self.xpath('pre[3]') - self.assertEqual('àç', pre.text) - - pre = self.xpath('pre[4]') - self.assertEqual('ç', pre.text) - def test_7(self): """Test case: strchr (7)""" self.start('Utf8/strchrs') - - pre = self.xpath('pre[1]') - self.assertEqual('None', pre.text) - - pre = self.xpath('pre[2]') - self.assertEqual('Some "bàç"', pre.text) - - pre = self.xpath('pre[3]') - self.assertEqual('Some "àç"', pre.text) - - pre = self.xpath('pre[4]') - self.assertEqual('Some "ç"', pre.text) - - pre = self.xpath('pre[5]') - self.assertEqual('Some ""', pre.text) def test_8(self): """Test case: strindex (8)""" self.start('Utf8/strindexs') - - pre = self.xpath('pre[1]') - self.assertEqual('None', pre.text) - - pre = self.xpath('pre[2]') - self.assertEqual('Some 0', pre.text) - - pre = self.xpath('pre[3]') - self.assertEqual('Some 1', pre.text) - - pre = self.xpath('pre[4]') - self.assertEqual('Some 2', pre.text) - - pre = self.xpath('pre[5]') - self.assertEqual('Some 3', pre.text) def test_9(self): """Test case: strindex (9)""" self.start('Utf8/strsindexs') - pre = self.xpath('pre[1]') - # behavior of strstr C function - self.assertEqual('Some 0', pre.text) - - pre = self.xpath('pre[2]') - self.assertEqual('Some 0', pre.text) - - pre = self.xpath('pre[3]') - self.assertEqual('None', pre.text) - - pre = self.xpath('pre[4]') - self.assertEqual('Some 1', pre.text) - - pre = self.xpath('pre[5]') - self.assertEqual('None', pre.text) - - pre = self.xpath('pre[6]') - self.assertEqual('Some 2', pre.text) - - pre = self.xpath('pre[7]') - self.assertEqual('None', pre.text) - - pre = self.xpath('pre[8]') - self.assertEqual('None', pre.text) - - pre = self.xpath('pre[9]') - self.assertEqual('Some 3', pre.text) - def test_10(self): """Test case: strcspn (10)""" self.start('Utf8/strcspns') - pre = self.xpath('pre[1]') - self.assertEqual('4', pre.text) - - pre = self.xpath('pre[2]') - self.assertEqual('0', pre.text) - - pre = self.xpath('pre[3]') - self.assertEqual('0', pre.text) - - pre = self.xpath('pre[4]') - self.assertEqual('1', pre.text) - - pre = self.xpath('pre[5]') - self.assertEqual('2', pre.text) - - pre = self.xpath('pre[6]') - self.assertEqual('3', pre.text) - def test_11(self): """Test case: str1 (11)""" self.start('Utf8/str1s') - pre = self.xpath('pre[1]') - self.assertEqual('a', pre.text) - - pre = self.xpath('pre[2]') - self.assertEqual('à', pre.text) - - pre = self.xpath('pre[3]') - self.assertEqual('á', pre.text) - def test_12(self): """Test case: isalnum (12)""" self.start('Utf8/isalnums') - - for idx in range(1, 9): - pre = self.xpath('pre[' + str(idx) + ']') - self.assertEqual('True', pre.text, 'Failed isalnum: assert ' + str(idx)) def test_13(self): """Test case: isalpha (13)""" self.start('Utf8/isalphas') - - for idx in range(1, 9): - pre = self.xpath('pre[' + str(idx) + ']') - self.assertEqual('True', pre.text, 'Failed isalpha: assert ' + str(idx)) def test_14(self): """Test case: isblank (14)""" self.start('Utf8/isblanks') - - for idx in range(1, 11): - pre = self.xpath('pre[' + str(idx) + ']') - self.assertEqual('True', pre.text, 'Failed isblank: assert ' + str(idx)) def test_15(self): """Test case: iscntrl (15)""" self.start('Utf8/iscntrls') - - for idx in range(1, 11): - pre = self.xpath('pre[' + str(idx) + ']') - self.assertEqual('True', pre.text, 'Failed iscntrl: assert ' + str(idx)) - + def test_16(self): """Test case: isdigit (16)""" self.start('Utf8/isdigits') - - for idx in range(1, 11): - pre = self.xpath('pre[' + str(idx) + ']') - self.assertEqual('True', pre.text, 'Failed isdigit: assert ' + str(idx)) - def test_17(self): """Test case: isgraph (17)""" self.start('Utf8/isgraphs') - for idx in range(1, 11): - pre = self.xpath('pre[' + str(idx) + ']') - self.assertEqual('True', pre.text, 'Failed isgraph: assert ' + str(idx)) - def test_18(self): """Test case: islower (18)""" self.start('Utf8/islowers') - for idx in range(1, 11): - pre = self.xpath('pre[' + str(idx) + ']') - self.assertEqual('True', pre.text, 'Failed islower: assert ' + str(idx)) - def test_19(self): """Test case: isprint (19)""" self.start('Utf8/isprints') - for idx in range(1, 11): - pre = self.xpath('pre[' + str(idx) + ']') - self.assertEqual('True', pre.text, 'Failed isprint: assert ' + str(idx)) - def test_20(self): """Test case: ispunct (20)""" self.start('Utf8/ispuncts') - for idx in range(1, 11): - pre = self.xpath('pre[' + str(idx) + ']') - self.assertEqual('True', pre.text, 'Failed ispunct: assert ' + str(idx)) - def test_21(self): """Test case: isspace (21)""" self.start('Utf8/isspaces') - for idx in range(1, 11): - pre = self.xpath('pre[' + str(idx) + ']') - self.assertEqual('True', pre.text, 'Failed isspace: assert ' + str(idx)) - def test_22(self): """Test case: isupper (22)""" self.start('Utf8/isuppers') - for idx in range(1, 11): - pre = self.xpath('pre[' + str(idx) + ']') - self.assertEqual('True', pre.text, 'Failed isupper: assert ' + str(idx)) - def test_23(self): """Test case: isxdigit (23)""" self.start('Utf8/isxdigits') - for idx in range(1, 11): - pre = self.xpath('pre[' + str(idx) + ']') - self.assertEqual('True', pre.text, 'Failed isxdigit: assert ' + str(idx)) - def test_24(self): """Test case: toupper (24)""" self.start('Utf8/touppers') - for idx in range(1, 6): - pre = self.xpath('pre[' + str(idx) + ']') - self.assertEqual('True', pre.text, 'Failed toupper: assert ' + str(idx)) - def test_25(self): """Test case: ord (25)""" self.start('Utf8/ord_and_chrs') - for idx in range(1, 8): - pre = self.xpath('pre[' + str(idx) + ']') - self.assertEqual('True', pre.text, 'Failed ord: assert ' + str(idx)) - def test_26 (self): """Test case: test_db (26) """ self.start('Utf8/test_db') - - pre = self.xpath('pre[1]') - self.assertEqual('abc', pre.text) - - pre = self.xpath('pre[2]') - self.assertEqual('3', pre.text) - - pre = self.xpath('pre[3]') - self.assertEqual('çãó', pre.text) - - pre = self.xpath('pre[4]') - self.assertEqual('3', pre.text) - - pre = self.xpath('pre[5]') - self.assertEqual('が', pre.text) - - pre = self.xpath('pre[6]') - self.assertEqual('1', pre.text) - - pre = self.xpath('pre[7]') - self.assertEqual('漢', pre.text) - - pre = self.xpath('pre[8]') - self.assertEqual('1', pre.text) - - pre = self.xpath('pre[9]') - self.assertEqual('カ', pre.text) - - pre = self.xpath('pre[10]') - self.assertEqual('1', pre.text) - - pre = self.xpath('pre[11]') - self.assertEqual('وظيفية', pre.text) - - pre = self.xpath('pre[12]') - self.assertEqual('6', pre.text) diff --git a/tests/utf8.ur b/tests/utf8.ur index 0dedc726..1038a59f 100644 --- a/tests/utf8.ur +++ b/tests/utf8.ur @@ -1,68 +1,104 @@ -fun substrings () : transaction page = return - -
{[substring "abc" 0 3]}
-
{[substring "abc" 1 2]}
-
{[substring "abc" 2 1]}
-
{[substring "ábó" 0 3]}
-
{[substring "ábó" 1 2]}
-
{[substring "ábó" 2 1]}
-
{[substring "çãó" 0 3]}
-
{[substring "çãó" 1 2]}
-
{[substring "çãó" 2 1]}
-
{[substring "çãó" 2 0]}
-
{[substring "" 0 0]}
- + +fun test_fn_both_sides [a ::: Type] (_ : eq a) (_ : show a) (f : unit -> a) (expected : a) (testname : string) : xbody = + +

Server side test: {[testname]}

+
{[assert (f () = expected) "False" testname "True" ]}
+

Client side test: {[testname]}

{[r]}
+ end}> +
+fun test_fn_sside [a ::: Type] (_ : eq a) (_ : show a) (f : unit -> a) (expected : a) (testname : string) : xbody = + +

Server side test: {[testname]}

+
{[assert (f () = expected) "False" testname "True" ]}
+
+ +fun substrings () : transaction page = + + return + + + {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"} + + + + fun strlens () : transaction page = return - -
{[strlen "abc"]}
-
{[strlen "çbc"]}
-
{[strlen "çãc"]}
-
{[strlen "çãó"]}
-
{[strlen "ç"]}
-
{[strlen "c"]}
-
{[strlen ""]}
-
{[strlen "が"]}
-
{[strlen "漢"]}
-
{[strlen "カ"]}
-
{[strlen "وظيفية"]}
-
{[strlen "函數"]}
-
{[strlen "Функциональное"]}
+ + {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"} +
fun strlenGens () : transaction page = return -
{[strlenGe "" 1]}
-
{[strlenGe "" 0]}
-
{[strlenGe "aba" 4]}
-
{[strlenGe "aba" 3]}
-
{[strlenGe "aba" 2]}
-
{[strlenGe "áçà" 4]}
-
{[strlenGe "áçà" 3]}
-
{[strlenGe "áçà" 2]}
+ {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"}
+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 catAndLen a b = - -
{[strcat a b]}
-
{[strlen (strcat a b)]}
-
+ 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 - {catAndLen "" ""} - {catAndLen "aa" "bb"} - {catAndLen "" "bb"} - {catAndLen "aa" ""} - {catAndLen "àà" "áá"} - {catAndLen "" "áá"} - {catAndLen "àà" ""} + {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} + end @@ -70,324 +106,303 @@ end fun strsubs () : transaction page = return -
{[strsub "abàç" 0]}
-
{[strsub "abàç" 1]}
-
{[strsub "abàç" 2]}
-
{[strsub "abàç" 3]}
+ {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"}
fun strsuffixs () : transaction page = return -
{[strsuffix "abàç" 0]}
-
{[strsuffix "abàç" 1]}
-
{[strsuffix "abàç" 2]}
-
{[strsuffix "abàç" 3]}
+ {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"}
fun strchrs () : transaction page = - let - fun optToStr ms = - case ms of - None => "None" - | Some s => "Some \"" ^ s ^ "\"" - - in - return - -
{[optToStr (strchr "abàç" #"c")]}
-
{[optToStr (strchr "abàç" #"a")]}
-
{[optToStr (strchr "abàç" #"b")]}
-
{[optToStr (strchr "abàç" (strsub "à" 0))]}
-
{[optToStr (strchr "abàç" (strsub "ç" 0))]}
- -
- end + return + + {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"} + + fun strindexs () : transaction page = - let - fun optToStr ms = - case ms of - None => "None" - | Some s => "Some " ^ (show s) - - in - return - -
{[optToStr (strindex "abàç" #"c")]}
-
{[optToStr (strindex "abàç" #"a")]}
-
{[optToStr (strindex "abàç" #"b")]}
-
{[optToStr (strindex "abàç" (strsub "à" 0))]}
-
{[optToStr (strindex "abàç" (strsub "ç" 0))]}
- -
- end + return + + {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"} + + + fun strsindexs () : transaction page = - let - fun optToStr ms = - case ms of - None => "None" - | Some s => "Some " ^ (show s) - - in - return - -
{[optToStr (strsindex "abàç" "")]}
-
{[optToStr (strsindex "abàç" "abàç")]}
-
{[optToStr (strsindex "abàç" "abàc")]}
-
{[optToStr (strsindex "abàç" "bàç")]}
-
{[optToStr (strsindex "abàç" "bàc")]}
-
{[optToStr (strsindex "abàç" "àç")]}
-
{[optToStr (strsindex "abàç" "àc")]}
-
{[optToStr (strsindex "abàç" "ac")]}
-
{[optToStr (strsindex "abàç" "ç")]}
- -
- end + return + + {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"} + + fun strcspns () : transaction page = return -
{[strcspn "abàç" ""]}
-
{[strcspn "abàç" "abàç"]}
-
{[strcspn "abàç" "a"]}
-
{[strcspn "abàç" "bàç"]}
-
{[strcspn "abàç" "àç"]}
-
{[strcspn "abàç" "ç"]}
+ {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"}
fun str1s () : transaction page = return -
{[str1 #"a"]}
-
{[str1 (strsub "à" 0)]}
-
{[str1 (strsub "aá" 1)]}
+ {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"}
fun isalnums () : transaction page = return -
{[isalnum #"a"]}
-
{[isalnum (strsub "à" 0)]}
-
{[isalnum #"A"]}
-
{[isalnum (strsub "À" 0)]}
-
{[isalnum #"1"]}
-
{[not (isalnum #"!")]}
-
{[not (isalnum #"#")]}
-
{[not (isalnum #" ")]}
+ {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"}
fun isalphas () : transaction page = return -
{[isalpha #"a"]}
-
{[isalpha (strsub "à" 0)]}
-
{[isalpha #"A"]}
-
{[isalpha (strsub "À" 0)]}
-
{[not (isalpha #"1")]}
-
{[not (isalpha #"!")]}
-
{[not (isalpha #"#")]}
-
{[not (isalpha #" ")]}
+ {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"}
fun isblanks () : transaction page = return -
{[not (isblank #"a")]}
-
{[not (isblank (strsub "à" 0))]}
-
{[not (isblank #"A")]}
-
{[not (isblank (strsub "À" 0))]}
-
{[not (isblank #"1")]}
-
{[not (isblank #"!")]}
-
{[not (isblank #"#")]}
-
{[isblank #" "]}
-
{[isblank #"\t"]}
-
{[not (isblank #"\n")]}
+ {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"}
fun iscntrls () : transaction page = return -
{[not (iscntrl #"a")]}
-
{[not (iscntrl (strsub "à" 0))]}
-
{[not (iscntrl #"A")]}
-
{[not (iscntrl (strsub "À" 0))]}
-
{[not (iscntrl #"1")]}
-
{[not (iscntrl #"!")]}
-
{[not (iscntrl #"#")]}
-
{[not (iscntrl #" ")]}
-
{[iscntrl #"\t"]}
-
{[iscntrl #"\n"]}
+ {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"}
fun isdigits () : transaction page = return -
{[not (isdigit #"a")]}
-
{[not (isdigit (strsub "à" 0))]}
-
{[not (isdigit #"A")]}
-
{[not (isdigit (strsub "À" 0))]}
-
{[isdigit #"1"]}
-
{[not (isdigit #"!")]}
-
{[not (isdigit #"#")]}
-
{[not (isdigit #" ")]}
-
{[not (isdigit #"\t")]}
-
{[not (isdigit #"\n")]}
+ {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"} -
+ fun isgraphs () : transaction page = return -
{[isgraph #"a"]}
-
{[isgraph (strsub "à" 0)]}
-
{[isgraph #"A"]}
-
{[isgraph (strsub "À" 0)]}
-
{[isgraph #"1"]}
-
{[isgraph #"!"]}
-
{[isgraph #"#"]}
-
{[not (isgraph #" ")]}
-
{[not (isgraph #"\t")]}
-
{[not (isdigit #"\n")]}
+ {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"} -
+ fun islowers () : transaction page = return -
{[islower #"a"]}
-
{[islower (strsub "à" 0)]}
-
{[not (islower #"A")]}
-
{[not (islower (strsub "À" 0))]}
-
{[not (islower #"1")]}
-
{[not (islower #"!")]}
-
{[not (islower #"#")]}
-
{[not (islower #" ")]}
-
{[not (islower #"\t")]}
-
{[not (islower #"\n")]}
+ {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"}
fun isprints () : transaction page = return -
{[isprint #"a"]}
-
{[isprint (strsub "à" 0)]}
-
{[isprint #"A"]}
-
{[isprint (strsub "À" 0)]}
-
{[isprint #"1"]}
-
{[isprint #"!"]}
-
{[isprint #"#"]}
-
{[isprint #" "]}
-
{[not (isprint #"\t")]}
-
{[not (isprint #"\n")]}
+ {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"}
fun ispuncts () : transaction page = return -
{[not (ispunct #"a")]}
-
{[not (ispunct (strsub "à" 0))]}
-
{[not (ispunct #"A")]}
-
{[not (ispunct (strsub "À" 0))]}
-
{[not (ispunct #"1")]}
-
{[ispunct #"!"]}
-
{[ispunct #"#"]}
-
{[not (ispunct #" ")]}
-
{[not (isprint #"\t")]}
-
{[not (isprint #"\n")]}
+ {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"}
fun isspaces () : transaction page = return -
{[not (isspace #"a")]}
-
{[not (isspace (strsub "à" 0))]}
-
{[not (isspace #"A")]}
-
{[not (isspace (strsub "À" 0))]}
-
{[not (isspace #"1")]}
-
{[not (isspace #"!")]}
-
{[not (isspace #"#")]}
-
{[isspace #" "]}
-
{[isspace #"\t"]}
-
{[isspace #"\n"]}
+ {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"}
fun isuppers () : transaction page = return -
{[not (isupper #"a")]}
-
{[not (isupper (strsub "à" 0))]}
-
{[isupper #"A"]}
-
{[isupper (strsub "À" 0)]}
-
{[not (isupper #"1")]}
-
{[not (isupper #"!")]}
-
{[not (isupper #"#")]}
-
{[not (isupper #" ")]}
-
{[not (isupper #"\t")]}
-
{[not (isupper #"\n")]}
+ {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"}
fun isxdigits () : transaction page = return -
{[isxdigit #"a"]}
-
{[not (isxdigit (strsub "à" 0))]}
-
{[isxdigit #"A"]}
-
{[not (isxdigit (strsub "À" 0))]}
-
{[isxdigit #"1"]}
-
{[not (isxdigit #"!")]}
-
{[not (isxdigit #"#")]}
-
{[not (isxdigit #" ")]}
-
{[not (isxdigit #"\t")]}
-
{[not (isxdigit #"\n")]}
+ {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"}
fun tolowers () : transaction page = return -
{[tolower #"A" = #"a"]}
-
{[tolower #"a" = #"a"]}
-
{[tolower (strsub "á" 0) = (strsub "á" 0)]}
-
{[tolower (strsub "Á" 0) = (strsub "á" 0)]}
-
{[tolower #"1" = #"1"]}
+ {test_fn_both_sides (fn _ => tolower #"A") #"a" "tolower 1"} + {test_fn_both_sides (fn _ => tolower #"a") #"a" "tolower 2"} + {test_fn_both_sides (fn _ => tolower (strsub "á" 0)) (strsub "á" 0) "tolower 3"} + {test_fn_both_sides (fn _ => tolower (strsub "Á" 0)) (strsub "á" 0) "tolower 4"} + {test_fn_both_sides (fn _ => tolower #"1") #"1" "tolower 5"}
fun touppers () : transaction page = return -
{[toupper #"A" = #"A"]}
-
{[toupper #"a" = #"A"]}
-
{[toupper (strsub "á" 0) = (strsub "Á" 0)]}
-
{[toupper (strsub "Á" 0) = (strsub "Á" 0)]}
-
{[toupper #"1" = #"1"]}
+ {test_fn_both_sides (fn _ => toupper #"A") #"A" "toupper 1"} + {test_fn_both_sides (fn _ => toupper #"a") #"A" "toupper 2"} + {test_fn_both_sides (fn _ => toupper (strsub "á" 0)) (strsub "Á" 0) "toupper 3"} + {test_fn_both_sides (fn _ => toupper (strsub "Á" 0)) (strsub "Á" 0) "toupper 4"} + {test_fn_both_sides (fn _ => toupper #"1") #"1" "toupper 5"}
fun ord_and_chrs () : transaction page = return -
{[chr (ord #"A") = #"A"]}
-
{[chr (ord #"a") = #"a"]}
-
{[chr (ord (strsub "á" 0)) = (strsub "á" 0)]}
-
{[chr (ord (strsub "Á" 0)) = (strsub "Á" 0)]}
-
{[chr (ord #"1") = #"1"]}
-
{[chr (ord #"\n") = #"\n"]}
-
{[chr (ord (strsub "が" 0)) = (strsub "が" 0)]}
-
{[chr (ord (strsub "漢" 0)) = (strsub "漢" 0)]}
-
{[chr (ord (strsub "カ" 0)) = (strsub "カ" 0)]}
+ {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"}
@@ -395,37 +410,77 @@ table t : { Id : int, Text : string } fun test_db () : transaction page = - dml (INSERT INTO t (Id, Text) VALUES({[1]}, {["abc"]})); + 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]}, {["çãó"]})); + 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]}, {["が"]})); + 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]}, {["漢"]})); + 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]}, {["カ"]})); + 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]}, {["وظيفية"]})); + dml (INSERT INTO t (Id, Text) VALUES({[6]}, {[s6]})); t6 <- oneRow (SELECT t.Text FROM t WHERE t.Id = 6); return -
{[t1.T.Text]}
-
{[strlen t1.T.Text]}
-
{[t2.T.Text]}
-
{[strlen t2.T.Text]}
-
{[t3.T.Text]}
-
{[strlen t3.T.Text]}
-
{[t4.T.Text]}
-
{[strlen t4.T.Text]}
-
{[t5.T.Text]}
-
{[strlen t5.T.Text]}
-
{[t6.T.Text]}
-
{[strlen t6.T.Text]}
+ {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)} + +
+ end + +fun index () : transaction page = + return + + substrings + strlens + strlenGens + strcats + strsubs + strsuffixs + strchrs + strindexs + strsindexs + strcspns + str1s + isalnums + isalphas + isblanks + iscntrls + isdigits + isgraphs + islowers + isprints + ispuncts + isspaces + isuppers + isxdigits + tolowers + touppers + ord_and_chrs + test_db diff --git a/tests/utf8.urp b/tests/utf8.urp index 9b3067af..25288aa8 100644 --- a/tests/utf8.urp +++ b/tests/utf8.urp @@ -2,4 +2,5 @@ database dbname=utf8 sql utf8.sql safeGet Utf8/test_db +$/option utf8 \ No newline at end of file -- cgit v1.2.3 From 5cc729b48aad084757a049b7e5cdbadae5e9e400 Mon Sep 17 00:00:00 2001 From: fab Date: Fri, 30 Nov 2018 23:29:14 +0000 Subject: reject invalid codepoints. Basis.iscodepoint. fix german char in js --- include/urweb/urweb_cpp.h | 5 +- lib/js/urweb.js | 7 +- lib/ur/basis.urs | 2 + src/c/urweb.c | 265 +++++++++++++++++++++++++++------------------- 4 files changed, 168 insertions(+), 111 deletions(-) (limited to 'src/c/urweb.c') 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 de1a2ad0..c7725e28 100644 --- a/lib/js/urweb.js +++ b/lib/js/urweb.js @@ -38,7 +38,12 @@ function isXdigit(c) { return isDigit(c) || (c >= 'a' && c <= 'f') || (c >= 'A' 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 toUpper(c) { + if (ord(c) == 223) + return c; + else + return c.toUpperCase(); +} // Lists diff --git a/lib/ur/basis.urs b/lib/ur/basis.urs index 878f2793..c9d6556b 100644 --- a/lib/ur/basis.urs +++ b/lib/ur/basis.urs @@ -79,6 +79,8 @@ val toupper : char -> char val ord : char -> int val chr : int -> char +val iscodepoint : int -> bool + (** String operations *) val strlen : string -> int diff --git a/src/c/urweb.c b/src/c/urweb.c index be65afcc..195ddada 100644 --- a/src/c/urweb.c +++ b/src/c/urweb.c @@ -1559,101 +1559,89 @@ const char *uw_Basis_get_settings(uw_context ctx, uw_unit u) { } } -uw_Basis_string uw_Basis_jsifyString(uw_context ctx, uw_Basis_string s) { - char *r, *s2; - - uw_check_heap(ctx, strlen(s) * 4 + 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; - } - } - } - - strcpy(s2, "\""); - ctx->heap.front = s2 + 2; - return r; -} - uw_Basis_bool uw_Basis_isprint(uw_context ctx, uw_Basis_char ch); - -uw_Basis_string uw_Basis_jsifyChar(uw_context ctx, uw_Basis_char c1) { - char *r, *s2; - - uw_check_heap(ctx, 7); - - r = s2 = ctx->heap.front; - *s2++ = '"'; - +void jsifyChar(char**buffer_ptr, uw_context ctx, uw_Basis_char c1) { + char* buffer = *buffer_ptr; + switch (c1) { case '"': - strcpy(s2, "\\\""); - s2 += 2; + strcpy(buffer, "\\\""); + buffer += 2; break; case '\'': - strcpy(s2, "\\047"); - s2 += 4; + strcpy(buffer, "\\047"); + buffer += 4; break; case '\\': - strcpy(s2, "\\\\"); - s2 += 2; + strcpy(buffer, "\\\\"); + buffer += 2; break; case '<': - strcpy(s2, "\\074"); - s2 += 4; + strcpy(buffer, "\\074"); + buffer += 4; break; case '&': - strcpy(s2, "\\046"); - s2 += 4; + strcpy(buffer, "\\046"); + buffer += 4; break; default: if (uw_Basis_isprint(ctx, c1) == uw_Basis_True) { int offset = 0; - U8_APPEND_UNSAFE(s2, offset, c1); - s2 += offset; + U8_APPEND_UNSAFE(buffer, offset, c1); + buffer += offset; } else { - assert(0777 >= c1); - sprintf(s2, "\\%03o", (unsigned char)c1); - s2 += 4; + assert(65536 > c1); + sprintf(buffer, "\\u%04x", (unsigned char)c1); + buffer += 6; } } + + *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) * 6 + 3); + + r = s2 = ctx->heap.front; + *s2++ = '"'; + + 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) { + char *r, *s2; + + uw_check_heap(ctx, 8); + + r = s2 = ctx->heap.front; + + *s2++ = '"'; + + jsifyChar(&s2, ctx, c1); + + strcpy(s2, "\""); + ctx->heap.front = s2 + 2; + return r; } @@ -1697,6 +1685,7 @@ uw_Basis_string uw_Basis_jsifyString_ws(uw_context ctx, uw_Basis_string s) { strcpy(s2, "\""); ctx->script.front = s2 + 1; + return r; } @@ -2262,25 +2251,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; } @@ -2328,48 +2319,69 @@ 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 offset = 0, len = 0; + + uw_check_heap(ctx, strlen(s) * (INTS_MAX + 3) + 1); - uw_check_heap(ctx, strlen(s) * 5 + 1); - - for (r = s2 = ctx->heap.front; *s; s++) { - unsigned char c = *s; - - switch (c) { - case '<': - strcpy(s2, "<"); - s2 += 4; - break; - case '&': - strcpy(s2, "&"); - s2 += 5; - break; - default: - *s2++ = c; + r = s2 = ctx->heap.front; + + while (s[offset] != 0) { + + U8_NEXT(s, offset, -1, c1); + + + if (U8_IS_SINGLE(c1) && uw_Basis_isprint(ctx, c1)) { + switch (c1) { + case '<': + strcpy(s2, "<"); + s2 += 4; + break; + case '&': + strcpy(s2, "&"); + s2 += 5; + break; + default: + *s2++ = c1; + } + } else { + len = sprintf(s2, "&#%u;", c1); + s2 += len; } } - + *s2++ = 0; ctx->heap.front = s2; + return r; } uw_unit uw_Basis_htmlifyString_w(uw_context ctx, uw_Basis_string s) { uw_check(ctx, strlen(s) * 6); - - for (; *s; s++) { - unsigned char c = *s; - - switch (c) { - case '<': - uw_write_unsafe(ctx, "<"); - break; - case '&': - uw_write_unsafe(ctx, "&"); - break; - default: - uw_writec_unsafe(ctx, c); + int offset = 0; + uw_Basis_char c1; + + while(s[offset] != 0){ + + U8_NEXT(s, offset, -1, c1); + + if (U8_IS_SINGLE(c1) && uw_Basis_isprint(ctx, c1)) { + + switch (c1) { + case '<': + uw_write_unsafe(ctx, "<"); + break; + case '&': + uw_write_unsafe(ctx, "&"); + break; + default: + uw_writec_unsafe(ctx, c1); + } } - } + else { + uw_Basis_htmlifySpecialChar_w(ctx, c1); + } + } return uw_unit_v; } @@ -4474,9 +4486,46 @@ uw_Basis_int uw_Basis_ord(uw_context ctx, uw_Basis_char c) { return (uw_Basis_int)c; } +uw_Basis_bool uw_Basis_iscodepoint (uw_context ctx, uw_Basis_int n) { + (void)ctx; + uw_Basis_char ch = (uw_Basis_char)n; + + if (UCHAR_MIN_VALUE <= ch && UCHAR_MAX_VALUE > ch) { + + if (U8_LENGTH(ch) == 0) { + return uw_Basis_False; + } + + if (u_charType(ch) == U_UNASSIGNED) { + return uw_Basis_False; + } + + } else { + return uw_Basis_False; + } + + return uw_Basis_True; +} + uw_Basis_char uw_Basis_chr(uw_context ctx, uw_Basis_int n) { (void)ctx; - return (uw_Basis_char)n; + uw_Basis_char ch = (uw_Basis_char)n; + + if (UCHAR_MIN_VALUE <= ch && UCHAR_MAX_VALUE > ch) { + + if (U8_LENGTH(ch) == 0) { + uw_error(ctx, FATAL, "The integer %lld cannot be converted to a char", n); + } + + if (u_charType(ch) == U_UNASSIGNED) { + uw_error(ctx, FATAL, "The integer %lld is not a valid char codepoint", n); + } + + } else { + uw_error(ctx, FATAL, "Integer %lld out of range of unicode chars", n); + } + + return ch; } uw_Basis_string uw_Basis_currentUrl(uw_context ctx) { -- cgit v1.2.3 From b50f472e65c0ffca5d485049325caa51298daa1a Mon Sep 17 00:00:00 2001 From: fab Date: Sun, 2 Dec 2018 00:46:46 +0000 Subject: 1 bug fix and sorting out my own confusion: uw_Basis_char is already a codepoint, NOT the "serialized" utf8 --- src/c/urweb.c | 37 ++++++------------------------------- tests/utf8.ur | 5 ++++- 2 files changed, 10 insertions(+), 32 deletions(-) (limited to 'src/c/urweb.c') diff --git a/src/c/urweb.c b/src/c/urweb.c index 195ddada..a4203376 100644 --- a/src/c/urweb.c +++ b/src/c/urweb.c @@ -1560,6 +1560,7 @@ 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; @@ -1594,7 +1595,7 @@ void jsifyChar(char**buffer_ptr, uw_context ctx, uw_Basis_char c1) { } else { assert(65536 > c1); - sprintf(buffer, "\\u%04x", (unsigned char)c1); + sprintf(buffer, "\\u%04x", c1); buffer += 6; } } @@ -4488,43 +4489,17 @@ uw_Basis_int uw_Basis_ord(uw_context ctx, uw_Basis_char c) { uw_Basis_bool uw_Basis_iscodepoint (uw_context ctx, uw_Basis_int n) { (void)ctx; - uw_Basis_char ch = (uw_Basis_char)n; - - if (UCHAR_MIN_VALUE <= ch && UCHAR_MAX_VALUE > ch) { - - if (U8_LENGTH(ch) == 0) { - return uw_Basis_False; - } - - if (u_charType(ch) == U_UNASSIGNED) { - return uw_Basis_False; - } - - } else { - return uw_Basis_False; - } - - return uw_Basis_True; + return !!(n <= 0x10FFFF); } uw_Basis_char uw_Basis_chr(uw_context ctx, uw_Basis_int n) { (void)ctx; uw_Basis_char ch = (uw_Basis_char)n; - if (UCHAR_MIN_VALUE <= ch && UCHAR_MAX_VALUE > ch) { - - if (U8_LENGTH(ch) == 0) { - uw_error(ctx, FATAL, "The integer %lld cannot be converted to a char", n); - } - - if (u_charType(ch) == U_UNASSIGNED) { - uw_error(ctx, FATAL, "The integer %lld is not a valid char codepoint", n); - } - - } else { - uw_error(ctx, FATAL, "Integer %lld out of range of unicode chars", n); + if (n > 0x10FFFF) { + uw_error(ctx, FATAL, "The integer %lld is not a valid char codepoint", n); } - + return ch; } diff --git a/tests/utf8.ur b/tests/utf8.ur index 07ac9c3d..e7c7fd40 100644 --- a/tests/utf8.ur +++ b/tests/utf8.ur @@ -100,7 +100,10 @@ fun strcats () : transaction page = {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 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} end -- cgit v1.2.3 From bc1547efbbad30da255b7c29973c94c8d37edabc Mon Sep 17 00:00:00 2001 From: fab Date: Sun, 2 Dec 2018 20:58:02 +0000 Subject: fix: U8_IS_SINGLE should only be called on raw char*, NOT on uw_Basis_char --- src/c/urweb.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'src/c/urweb.c') diff --git a/src/c/urweb.c b/src/c/urweb.c index a4203376..d622df87 100644 --- a/src/c/urweb.c +++ b/src/c/urweb.c @@ -2321,18 +2321,17 @@ 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 offset = 0, len = 0; + int oldoffset = 0, offset = 0, offset2 = 0, len = 0; uw_check_heap(ctx, strlen(s) * (INTS_MAX + 3) + 1); r = s2 = ctx->heap.front; while (s[offset] != 0) { - + oldoffset = offset; U8_NEXT(s, offset, -1, c1); - - - if (U8_IS_SINGLE(c1) && uw_Basis_isprint(ctx, c1)) { + + if ((offset - oldoffset == 1) && uw_Basis_isprint(ctx, c1)) { switch (c1) { case '<': strcpy(s2, "<"); @@ -2343,7 +2342,9 @@ char *uw_Basis_htmlifyString(uw_context ctx, const char *s) { s2 += 5; break; default: - *s2++ = c1; + offset2 = 0; + U8_APPEND_UNSAFE(s2, offset2, c1); + s2 += offset2; } } else { len = sprintf(s2, "&#%u;", c1); @@ -2353,20 +2354,19 @@ char *uw_Basis_htmlifyString(uw_context ctx, const char *s) { *s2++ = 0; ctx->heap.front = s2; - return r; } uw_unit uw_Basis_htmlifyString_w(uw_context ctx, uw_Basis_string s) { uw_check(ctx, strlen(s) * 6); - int offset = 0; + int offset = 0, oldoffset = 0; uw_Basis_char c1; while(s[offset] != 0){ - + oldoffset = offset; U8_NEXT(s, offset, -1, c1); - if (U8_IS_SINGLE(c1) && uw_Basis_isprint(ctx, c1)) { + if ((offset - oldoffset == 1) && uw_Basis_isprint(ctx, c1)) { switch (c1) { case '<': -- cgit v1.2.3 From df191c8374991f65c5f5a552cfa5f4fb08fe29e8 Mon Sep 17 00:00:00 2001 From: fab Date: Thu, 6 Dec 2018 21:24:04 +0000 Subject: chars with more than 2 bytes are awkwardly handled by the "normal" string of javascript. the best way to get consistent results seems to be to convert to array by Array.from(...) and back to strings with .join("") --- lib/js/urweb.js | 14 +++++++------- src/c/urweb.c | 14 +++++++++----- tests/utf8.ur | 20 ++++++++++++++++++++ 3 files changed, 36 insertions(+), 12 deletions(-) (limited to 'src/c/urweb.c') diff --git a/lib/js/urweb.js b/lib/js/urweb.js index c7725e28..e28446e3 100644 --- a/lib/js/urweb.js +++ b/lib/js/urweb.js @@ -1462,9 +1462,9 @@ 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].codePointAt(0); } +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); if (r == -1) @@ -1494,10 +1494,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) { @@ -1596,11 +1596,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) + ";"; } diff --git a/src/c/urweb.c b/src/c/urweb.c index d622df87..1394e068 100644 --- a/src/c/urweb.c +++ b/src/c/urweb.c @@ -1594,9 +1594,13 @@ void jsifyChar(char**buffer_ptr, uw_context ctx, uw_Basis_char c1) { buffer += offset; } else { - assert(65536 > c1); - sprintf(buffer, "\\u%04x", c1); - buffer += 6; + if(65536 > c1) { + sprintf(buffer, "\\u%04x", c1); + buffer += 6; + } else { + sprintf(buffer, "\\u{%06x}", c1); + buffer += 10; + } } } @@ -1608,7 +1612,7 @@ 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) * 6 + 3); + uw_check_heap(ctx, strlen(s) * 10 + 3); r = s2 = ctx->heap.front; *s2++ = '"'; @@ -1632,7 +1636,7 @@ 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) { char *r, *s2; - uw_check_heap(ctx, 8); + uw_check_heap(ctx, 10); r = s2 = ctx->heap.front; diff --git a/tests/utf8.ur b/tests/utf8.ur index e7c7fd40..cf781fa9 100644 --- a/tests/utf8.ur +++ b/tests/utf8.ur @@ -31,6 +31,25 @@ fun test_fn_cside [a ::: Type] (_ : eq a) (_ : show a) (f : unit -> a) (expected +fun highencode () : transaction page = + return + + {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"} + + + + fun substrings () : transaction page = return @@ -510,6 +529,7 @@ fun index () : transaction page = touppers ord_and_chrs test ord + highencode test_db -- cgit v1.2.3 From 1dd8c0c06f27343f86fd16b2c52b872871d0ab10 Mon Sep 17 00:00:00 2001 From: fab Date: Sun, 9 Dec 2018 22:23:41 +0000 Subject: fix isxdigit: is probably helpful to keep it only to ascii chars. migrate islower, isupper, isalpha, isdigit, isblank, isspace, isxdigit, isprint --- lib/js/urweb.js | 2778 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- src/c/urweb.c | 2 +- 2 files changed, 2708 insertions(+), 72 deletions(-) (limited to 'src/c/urweb.c') diff --git a/lib/js/urweb.js b/lib/js/urweb.js index 05ee2a17..fe47959f 100644 --- a/lib/js/urweb.js +++ b/lib/js/urweb.js @@ -27,130 +27,2766 @@ function le(x, y) { return x <= y; } // Characters -function isLower(c) { return toLower(c) == c && c != toUpper(c); } -function isUpper(c) { return toUpper(c) == c && c != toLower(c); } -function isAlpha(c) { return isLower(c) || isUpper(c); } +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 && c <= 57) + if (cp >= 48 && cp <= 57) return true; - else if (cp >= 1632 && cp <= 1641) + if (cp >= 1632 && cp <= 1641) return true; - else if (cp >= 1776 && cp <= 1785) + if (cp >= 1776 && cp <= 1785) return true; - else if (cp >= 1984 && cp <= 1993) + if (cp >= 1984 && cp <= 1993) return true; - else if (cp >= 2406 && cp <= 2415) + if (cp >= 2406 && cp <= 2415) return true; - else if (cp >= 2534 && cp <= 2543) + if (cp >= 2534 && cp <= 2543) return true; - else if (cp >= 2662 && cp <= 2671) + if (cp >= 2662 && cp <= 2671) return true; - else if (cp >= 2790 && cp <= 2799) + if (cp >= 2790 && cp <= 2799) return true; - else if (cp >= 2918 && cp <= 2927) + if (cp >= 2918 && cp <= 2927) return true; - else if (cp >= 3046 && cp <= 3055) + if (cp >= 3046 && cp <= 3055) return true; - else if (cp >= 3174 && cp <= 3183) + if (cp >= 3174 && cp <= 3183) return true; - else if (cp >= 3302 && cp <= 3311) + if (cp >= 3302 && cp <= 3311) return true; - else if (cp >= 3430 && cp <= 3439) + if (cp >= 3430 && cp <= 3439) return true; - else if (cp >= 3558 && cp <= 3567) + if (cp >= 3558 && cp <= 3567) return true; - else if (cp >= 3664 && cp <= 3673) + if (cp >= 3664 && cp <= 3673) return true; - else if (cp >= 3792 && cp <= 3801) + if (cp >= 3792 && cp <= 3801) return true; - else if (cp >= 3872 && cp <= 3881) + if (cp >= 3872 && cp <= 3881) return true; - else if (cp >= 4160 && cp <= 4169) + if (cp >= 4160 && cp <= 4169) return true; - else if (cp >= 4240 && cp <= 4249) + if (cp >= 4240 && cp <= 4249) return true; - else if (cp >= 6112 && cp <= 6121) + if (cp >= 6112 && cp <= 6121) return true; - else if (cp >= 6160 && cp <= 6169) + if (cp >= 6160 && cp <= 6169) return true; - else if (cp >= 6470 && cp <= 6479) + if (cp >= 6470 && cp <= 6479) return true; - else if (cp >= 6608 && cp <= 6617) + if (cp >= 6608 && cp <= 6617) return true; - else if (cp >= 6784 && cp <= 6793) + if (cp >= 6784 && cp <= 6793) return true; - else if (cp >= 6800 && cp <= 6809) + if (cp >= 6800 && cp <= 6809) return true; - else if (cp >= 6992 && cp <= 7001) + if (cp >= 6992 && cp <= 7001) return true; - else if (cp >= 7088 && cp <= 7097) + if (cp >= 7088 && cp <= 7097) return true; - else if (cp >= 7232 && cp <= 7241) + if (cp >= 7232 && cp <= 7241) return true; - else if (cp >= 7248 && cp <= 7257) + if (cp >= 7248 && cp <= 7257) return true; - else if (cp >= 42528 && cp <= 42537) + if (cp >= 42528 && cp <= 42537) return true; - else if (cp >= 43216 && cp <= 43225) + if (cp >= 43216 && cp <= 43225) return true; - else if (cp >= 43264 && cp <= 43273) + if (cp >= 43264 && cp <= 43273) return true; - else if (cp >= 43472 && cp <= 43481) + if (cp >= 43472 && cp <= 43481) return true; - else if (cp >= 43504 && cp <= 43513) + if (cp >= 43504 && cp <= 43513) return true; - else if (cp >= 43600 && cp <= 43609) + if (cp >= 43600 && cp <= 43609) return true; - else if (cp >= 44016 && cp <= 44025) + if (cp >= 44016 && cp <= 44025) return true; - else if (cp >= 65296 && cp <= 65305) + if (cp >= 65296 && cp <= 65305) return true; - else if (cp >= 66720 && cp <= 66729) + if (cp >= 66720 && cp <= 66729) return true; - else if (cp >= 69734 && cp <= 69743) + if (cp >= 69734 && cp <= 69743) return true; - else if (cp >= 69872 && cp <= 69881) + if (cp >= 69872 && cp <= 69881) return true; - else if (cp >= 69942 && cp <= 69951) + if (cp >= 69942 && cp <= 69951) return true; - else if (cp >= 70096 && cp <= 70105) + if (cp >= 70096 && cp <= 70105) return true; - else if (cp >= 70384 && cp <= 70393) + if (cp >= 70384 && cp <= 70393) return true; - else if (cp >= 70736 && cp <= 70745) + if (cp >= 70736 && cp <= 70745) return true; - else if (cp >= 70864 && cp <= 70873) + if (cp >= 70864 && cp <= 70873) return true; - else if (cp >= 71248 && cp <= 71257) + if (cp >= 71248 && cp <= 71257) return true; - else if (cp >= 71360 && cp <= 71369) + if (cp >= 71360 && cp <= 71369) return true; - else if (cp >= 71472 && cp <= 71481) + if (cp >= 71472 && cp <= 71481) return true; - else if (cp >= 71904 && cp <= 71913) + if (cp >= 71904 && cp <= 71913) return true; - else if (cp >= 72784 && cp <= 72793) + if (cp >= 72784 && cp <= 72793) return true; - else if (cp >= 73040 && cp <= 73049) + if (cp >= 73040 && cp <= 73049) return true; - else if (cp >= 92768 && cp <= 92777) + if (cp >= 92768 && cp <= 92777) return true; - else if (cp >= 93008 && cp <= 93017) + if (cp >= 93008 && cp <= 93017) return true; - else if (cp >= 120782 && cp <= 120831) + if (cp >= 120782 && cp <= 120831) return true; - else if (cp >= 125264 && cp <= 125273) + 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.codePointAt(0); } -function isPrint(c) { return ord(c) > 31 && ord(c) != 127; } +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) + return true; + if (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); @@ -277,7 +2913,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) { @@ -299,8 +2935,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; } @@ -449,11 +3085,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) diff --git a/src/c/urweb.c b/src/c/urweb.c index 1394e068..e458a706 100644 --- a/src/c/urweb.c +++ b/src/c/urweb.c @@ -4473,7 +4473,7 @@ uw_Basis_bool uw_Basis_isupper(uw_context ctx, uw_Basis_char c) { uw_Basis_bool uw_Basis_isxdigit(uw_context ctx, uw_Basis_char c) { (void)ctx; - return !!u_hasBinaryProperty(c, UCHAR_POSIX_XDIGIT); + return !!(c <= 0x7f && u_isxdigit(c)); } uw_Basis_char uw_Basis_tolower(uw_context ctx, uw_Basis_char c) { -- cgit v1.2.3 From 1ce628ae2ab01799b6f601f0677ea396d1ac1577 Mon Sep 17 00:00:00 2001 From: fab Date: Tue, 11 Dec 2018 20:44:50 +0000 Subject: migrate is_valid_hash, blessData, property, atom --- lib/js/urweb.js | 39 ++++++++++++++++++++++++--------------- src/c/urweb.c | 20 ++++++++++---------- 2 files changed, 34 insertions(+), 25 deletions(-) (limited to 'src/c/urweb.c') diff --git a/lib/js/urweb.js b/lib/js/urweb.js index fe47959f..00637172 100644 --- a/lib/js/urweb.js +++ b/lib/js/urweb.js @@ -5109,11 +5109,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"); } @@ -5124,9 +5127,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"); } @@ -5134,10 +5139,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"); } @@ -5145,15 +5152,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/src/c/urweb.c b/src/c/urweb.c index e458a706..96e30cec 100644 --- a/src/c/urweb.c +++ b/src/c/urweb.c @@ -1975,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); @@ -2067,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); @@ -4758,7 +4758,7 @@ uw_Basis_string uw_Basis_atom(uw_context ctx, uw_Basis_string s) { for (p = s; *p; ++p) { char c = *p; - if (!U8_IS_SINGLE(c) && !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"); } @@ -4770,8 +4770,8 @@ uw_Basis_string uw_Basis_css_url(uw_context ctx, uw_Basis_string s) { for (p = s; *p; ++p) { char c = *p; - if (!U8_IS_SINGLE(c) && !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"); } @@ -4784,12 +4784,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 (!U8_IS_SINGLE(c) && !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"); } @@ -4840,9 +4840,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; @@ -5174,7 +5174,7 @@ int strcmp_nullsafe(const char *str1, const char *str2) { static int is_valid_hash(uw_Basis_string hash) { for (; *hash; ++hash) - if (!U8_IS_SINGLE(*hash) && !isxdigit(*hash)) + if (!U8_IS_SINGLE(*hash) || !isxdigit(*hash)) return 0; return 1; -- cgit v1.2.3 From e452bb052b6c1afbaaa72efb653ea31561333866 Mon Sep 17 00:00:00 2001 From: fab Date: Tue, 11 Dec 2018 22:16:37 +0000 Subject: exhaustive testing brought to selenium. bug fix in isspace. useful function to test if char is <128 --- lib/js/urweb.js | 5 +- lib/ur/basis.urs | 1 + src/c/urweb.c | 5 ++ tests/utf8.py | 79 +++++++++++++++++--- tests/utf8.ur | 217 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 292 insertions(+), 15 deletions(-) (limited to 'src/c/urweb.c') diff --git a/lib/js/urweb.js b/lib/js/urweb.js index 00637172..2d39bc69 100644 --- a/lib/js/urweb.js +++ b/lib/js/urweb.js @@ -2122,9 +2122,7 @@ function isBlank(c) { } function isSpace(c) { var cp = ord(c); - if (cp == 10) - return true; - if (cp == 13) + if (cp >= 10 && cp <= 13) return true; if (cp == 133) return true; @@ -2790,6 +2788,7 @@ function isPrint(c) { function toLower(c) { var cp = ord(c); + if (cp == 304) return chr(105); else if (cp >= 7312 && cp <= 7354) diff --git a/lib/ur/basis.urs b/lib/ur/basis.urs index c9d6556b..c893e65d 100644 --- a/lib/ur/basis.urs +++ b/lib/ur/basis.urs @@ -80,6 +80,7 @@ val ord : char -> int val chr : int -> char val iscodepoint : int -> bool +val issingle : char -> bool (** String operations *) diff --git a/src/c/urweb.c b/src/c/urweb.c index 96e30cec..78946872 100644 --- a/src/c/urweb.c +++ b/src/c/urweb.c @@ -4496,6 +4496,11 @@ uw_Basis_bool uw_Basis_iscodepoint (uw_context ctx, uw_Basis_int n) { 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; uw_Basis_char ch = (uw_Basis_char)n; diff --git a/tests/utf8.py b/tests/utf8.py index 440bc82a..ac8df5c3 100644 --- a/tests/utf8.py +++ b/tests/utf8.py @@ -2,51 +2,51 @@ import unittest import base class Suite(base.Base): - def test_1(self): + def test_99(self): """Test case: substring (1)""" self.start('Utf8/substrings') - def test_2(self): + def test_98(self): """Test case: strlen (2)""" self.start('Utf8/strlens') - def test_3(self): + def test_97(self): """Test case: strlenGe (3)""" self.start('Utf8/strlenGens') - def test_4(self): + def test_96(self): """Test case: strcat (4)""" self.start('Utf8/strcats') - def test_5(self): + def test_95(self): """Test case: strsub (5)""" self.start('Utf8/strsubs') - def test_6(self): + def test_94(self): """Test case: strsuffix (6)""" self.start('Utf8/strsuffixs') - def test_7(self): + def test_93(self): """Test case: strchr (7)""" self.start('Utf8/strchrs') - def test_8(self): + def test_92(self): """Test case: strindex (8)""" self.start('Utf8/strindexs') - def test_9(self): + def test_91(self): """Test case: strindex (9)""" self.start('Utf8/strsindexs') - def test_10(self): + def test_90(self): """Test case: strcspn (10)""" self.start('Utf8/strcspns') - def test_11(self): + def test_89(self): """Test case: str1 (11)""" self.start('Utf8/str1s') - def test_12(self): + def test_88(self): """Test case: isalnum (12)""" self.start('Utf8/isalnums') @@ -105,3 +105,58 @@ class Suite(base.Base): def test_26 (self): """Test case: test_db (26) """ self.start('Utf8/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_1 (self): + """Test case: ftTolower """ + self.full_test("ftTolower") + + def test_2 (self): + """Test case: ftToupper """ + self.full_test("ftToupper") + + def test_3 (self): + """Test case: ftIsalpha """ + self.full_test("ftIsalpha") + + def test_4 (self): + """Test case: ftIsdigit """ + self.full_test("ftIsdigit") + + def test_5 (self): + """Test case: ftIsalnum """ + self.full_test("ftIsalnum") + + def test_6 (self): + """Test case: ftIsspace """ + self.full_test("ftIsspace") + + def test_7 (self): + """Test case: ftIsblank """ + self.full_test("ftIsblank") + + def test_8 (self): + """Test case: ftIsprint """ + self.full_test("ftIsprint") + + def test_9 (self): + """Test case: ftIsxdigit """ + self.full_test("ftIsxdigit") + + def test_10 (self): + """Test case: ftIsupper """ + self.full_test("ftIsupper") + + def test_11 (self): + """Test case: ftIslower """ + self.full_test("ftIslower") diff --git a/tests/utf8.ur b/tests/utf8.ur index c7aefd79..777bb141 100644 --- a/tests/utf8.ur +++ b/tests/utf8.ur @@ -1,4 +1,13 @@ +fun from_m_upto_n f m n = + if m < n then + + { f m } + { from_m_upto_n f (m + 1) n } + + else + + fun test_fn_both_sides [a ::: Type] (_ : eq a) (_ : show a) (f : unit -> a) (expected : a) (testname : string) : xbody =

Server side test: {[testname]}

@@ -31,6 +40,38 @@ fun test_fn_cside [a ::: Type] (_ : eq a) (_ : show a) (f : unit -> a) (expected
+ +fun test_fn_cside_ch (f : unit -> char) (expected : char) (testname : string) : xbody = + + + else + return

ERROR {[testname]}: {[msgErr]}

+ end}> + + + +fun test_fn_cside_b (f : unit -> bool) (expected : bool) (testname : string) : xbody = + + + else + return

ERROR {[testname]}: {[msgErr]}

+ end}> + + + + fun highencode () : transaction page = return @@ -553,6 +594,182 @@ fun test_db () : transaction page = 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 + + in + return + + { from_m_upto_n (fn n => test_chr n) minCh maxCh } + + + 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 + + in + return + + { from_m_upto_n (fn n => test_chr n) minCh maxCh } + + + 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 + + in + return + + { from_m_upto_n (fn n => test_chr n) minCh maxCh } + + + 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 + + in + return + + { from_m_upto_n (fn n => test_chr n) minCh maxCh } + + + 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 + + in + return + + { from_m_upto_n (fn n => test_chr n) minCh maxCh } + + + 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 + + in + return + + { from_m_upto_n (fn n => test_chr n) minCh maxCh } + + + 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 + + in + return + + { from_m_upto_n (fn n => test_chr n) minCh maxCh } + + + 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 + + in + return + + { from_m_upto_n (fn n => test_chr n) minCh maxCh } + + + 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 + + in + return + + { from_m_upto_n (fn n => test_chr n) minCh maxCh } + + + 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 + + in + return + + { from_m_upto_n (fn n => test_chr n) minCh maxCh } + + + 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 + + in + return + + { from_m_upto_n (fn n => test_chr n) minCh maxCh } + + + end + fun index () : transaction page = return -- cgit v1.2.3