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. --- .travis.yml | 2 +- include/urweb/types_cpp.h | 3 +- src/c/Makefile.am | 2 +- src/c/urweb.c | 197 +++++++++++++------- src/compiler.sml | 4 +- tests/Makefile | 2 + tests/utf8.py | 449 ++++++++++++++++++++++++++++++++++++++++++++++ tests/utf8.ur | 431 ++++++++++++++++++++++++++++++++++++++++++++ tests/utf8.urp | 5 + 9 files changed, 1024 insertions(+), 71 deletions(-) create mode 100644 tests/utf8.py create mode 100644 tests/utf8.ur create mode 100644 tests/utf8.urp diff --git a/.travis.yml b/.travis.yml index df4e4abc..86d731cc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,7 +18,7 @@ compiler: before_install: - export CONFIGURE_ARGS="" - if command -v apt-get &>/dev/null; then sudo apt-get update -qq; fi - - if command -v apt-get &>/dev/null; then sudo apt-get install -y mlton; fi + - if command -v apt-get &>/dev/null; then sudo apt-get install -y mlton lib-icudev; fi - if command -v brew &>/dev/null; then brew update; fi - if command -v brew &>/dev/null; then brew uninstall libtool; fi - if command -v brew &>/dev/null; then brew install libtool; fi diff --git a/include/urweb/types_cpp.h b/include/urweb/types_cpp.h index 0c546d1c..c6c0dd3e 100644 --- a/include/urweb/types_cpp.h +++ b/include/urweb/types_cpp.h @@ -4,11 +4,12 @@ #include #include #include +#include typedef long long uw_Basis_int; typedef double uw_Basis_float; typedef char* uw_Basis_string; -typedef char uw_Basis_char; +typedef UChar32 uw_Basis_char; typedef struct { time_t seconds; unsigned microseconds; diff --git a/src/c/Makefile.am b/src/c/Makefile.am index 027b1458..96c1d92f 100644 --- a/src/c/Makefile.am +++ b/src/c/Makefile.am @@ -11,7 +11,7 @@ AM_CFLAGS = -Wall -Wunused-parameter -Werror -Wno-format-security -Wno-deprecate liburweb_la_LDFLAGS = $(AM_LDFLAGS) $(OPENSSL_LDFLAGS) \ -export-symbols-regex '^(client_pruner|pthread_create_big|strcmp_nullsafe|uw_.*)' \ -version-info 1:0:0 -liburweb_la_LIBADD = $(PTHREAD_LIBS) -lm $(OPENSSL_LIBS) +liburweb_la_LIBADD = $(PTHREAD_LIBS) -lm $(OPENSSL_LIBS) -licui18n -licuuc -licudata liburweb_http_la_LIBADD = liburweb.la liburweb_http_la_LDFLAGS = -export-symbols-regex '^(main|uw_.*)' \ -version-info 1:0:0 diff --git a/src/c/urweb.c b/src/c/urweb.c index 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; diff --git a/src/compiler.sml b/src/compiler.sml index f724bf56..9ee88c9b 100644 --- a/src/compiler.sml +++ b/src/compiler.sml @@ -1585,9 +1585,9 @@ fun compileC {cname, oname, ename, libs, profile, debug, linker, link = link'} = val proto = Settings.currentProtocol () val lib = if Settings.getBootLinking () then - !Settings.configLib ^ "/" ^ #linkStatic proto ^ " " ^ !Settings.configLib ^ "/liburweb.a" + !Settings.configLib ^ "/" ^ #linkStatic proto ^ " " ^ !Settings.configLib ^ "/liburweb.a -licui18n -licuuc -licudata" else if Settings.getStaticLinking () then - " -static " ^ !Settings.configLib ^ "/" ^ #linkStatic proto ^ " " ^ !Settings.configLib ^ "/liburweb.a" + " -static " ^ !Settings.configLib ^ "/" ^ #linkStatic proto ^ " " ^ !Settings.configLib ^ "/liburweb.a -licui18n -licuuc -licudata" else "-L" ^ !Settings.configLib ^ " " ^ #linkDynamic proto ^ " -lurweb" diff --git a/tests/Makefile b/tests/Makefile index ecf5557b..03e37e4b 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -28,3 +28,5 @@ simple:: ./driver.sh fact ./driver.sh filter ./driver.sh jsbspace + ./driver.sh utf8 + diff --git a/tests/utf8.py b/tests/utf8.py new file mode 100644 index 00000000..ff9b737a --- /dev/null +++ b/tests/utf8.py @@ -0,0 +1,449 @@ +import unittest +import base + +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 new file mode 100644 index 00000000..0dedc726 --- /dev/null +++ b/tests/utf8.ur @@ -0,0 +1,431 @@ +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 strlens () : transaction page = return + +
{[strlen "abc"]}
+
{[strlen "çbc"]}
+
{[strlen "çãc"]}
+
{[strlen "çãó"]}
+
{[strlen "ç"]}
+
{[strlen "c"]}
+
{[strlen ""]}
+
{[strlen "が"]}
+
{[strlen "漢"]}
+
{[strlen "カ"]}
+
{[strlen "وظيفية"]}
+
{[strlen "函數"]}
+
{[strlen "Функциональное"]}
+ +
+ +fun strlenGens () : transaction page = return + +
{[strlenGe "" 1]}
+
{[strlenGe "" 0]}
+
{[strlenGe "aba" 4]}
+
{[strlenGe "aba" 3]}
+
{[strlenGe "aba" 2]}
+
{[strlenGe "áçà" 4]}
+
{[strlenGe "áçà" 3]}
+
{[strlenGe "áçà" 2]}
+ + +
+ +fun strcats () : transaction page = + let + fun catAndLen a b = + +
{[strcat a b]}
+
{[strlen (strcat a b)]}
+
+ in + return + + {catAndLen "" ""} + {catAndLen "aa" "bb"} + {catAndLen "" "bb"} + {catAndLen "aa" ""} + {catAndLen "àà" "áá"} + {catAndLen "" "áá"} + {catAndLen "àà" ""} + + +end + +fun strsubs () : transaction page = + return + +
{[strsub "abàç" 0]}
+
{[strsub "abàç" 1]}
+
{[strsub "abàç" 2]}
+
{[strsub "abàç" 3]}
+ +
+ +fun strsuffixs () : transaction page = + return + +
{[strsuffix "abàç" 0]}
+
{[strsuffix "abàç" 1]}
+
{[strsuffix "abàç" 2]}
+
{[strsuffix "abàç" 3]}
+ +
+ +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 + +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 + +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 + +fun strcspns () : transaction page = + return + +
{[strcspn "abàç" ""]}
+
{[strcspn "abàç" "abàç"]}
+
{[strcspn "abàç" "a"]}
+
{[strcspn "abàç" "bàç"]}
+
{[strcspn "abàç" "àç"]}
+
{[strcspn "abàç" "ç"]}
+ +
+ +fun str1s () : transaction page = return + +
{[str1 #"a"]}
+
{[str1 (strsub "à" 0)]}
+
{[str1 (strsub "aá" 1)]}
+ +
+ +fun isalnums () : transaction page = return + +
{[isalnum #"a"]}
+
{[isalnum (strsub "à" 0)]}
+
{[isalnum #"A"]}
+
{[isalnum (strsub "À" 0)]}
+
{[isalnum #"1"]}
+
{[not (isalnum #"!")]}
+
{[not (isalnum #"#")]}
+
{[not (isalnum #" ")]}
+ +
+ +fun isalphas () : transaction page = return + +
{[isalpha #"a"]}
+
{[isalpha (strsub "à" 0)]}
+
{[isalpha #"A"]}
+
{[isalpha (strsub "À" 0)]}
+
{[not (isalpha #"1")]}
+
{[not (isalpha #"!")]}
+
{[not (isalpha #"#")]}
+
{[not (isalpha #" ")]}
+ +
+ +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")]}
+ +
+ +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"]}
+ +
+ +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")]}
+ +
+ +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")]}
+ +
+ +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")]}
+ +
+ +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")]}
+ +
+ +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")]}
+ +
+ +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"]}
+ +
+ +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")]}
+ +
+ +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")]}
+ +
+ +fun tolowers () : transaction page = + return + +
{[tolower #"A" = #"a"]}
+
{[tolower #"a" = #"a"]}
+
{[tolower (strsub "á" 0) = (strsub "á" 0)]}
+
{[tolower (strsub "Á" 0) = (strsub "á" 0)]}
+
{[tolower #"1" = #"1"]}
+ +
+ +fun touppers () : transaction page = + return + +
{[toupper #"A" = #"A"]}
+
{[toupper #"a" = #"A"]}
+
{[toupper (strsub "á" 0) = (strsub "Á" 0)]}
+
{[toupper (strsub "Á" 0) = (strsub "Á" 0)]}
+
{[toupper #"1" = #"1"]}
+ +
+ +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)]}
+ +
+ +table t : { Id : int, Text : string } + + +fun test_db () : transaction page = + dml (INSERT INTO t (Id, Text) VALUES({[1]}, {["abc"]})); + t1 <- oneRow (SELECT t.Text FROM t WHERE t.Id = 1); + + dml (INSERT INTO t (Id, Text) VALUES({[2]}, {["çãó"]})); + t2 <- oneRow (SELECT t.Text FROM t WHERE t.Id = 2); + + dml (INSERT INTO t (Id, Text) VALUES({[3]}, {["が"]})); + t3 <- oneRow (SELECT t.Text FROM t WHERE t.Id = 3); + + dml (INSERT INTO t (Id, Text) VALUES({[4]}, {["漢"]})); + t4 <- oneRow (SELECT t.Text FROM t WHERE t.Id = 4); + + dml (INSERT INTO t (Id, Text) VALUES({[5]}, {["カ"]})); + t5 <- oneRow (SELECT t.Text FROM t WHERE t.Id = 5); + + dml (INSERT INTO t (Id, Text) VALUES({[6]}, {["وظيفية"]})); + 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]}
+ +
diff --git a/tests/utf8.urp b/tests/utf8.urp new file mode 100644 index 00000000..9b3067af --- /dev/null +++ b/tests/utf8.urp @@ -0,0 +1,5 @@ +database dbname=utf8 +sql utf8.sql +safeGet Utf8/test_db + +utf8 \ No newline at end of file -- cgit v1.2.3 From 6caadfc4b175f4703cff9776939478ccdf8abc2d Mon Sep 17 00:00:00 2001 From: fab Date: Sat, 17 Nov 2018 22:31:42 +0000 Subject: fix package name --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 86d731cc..a36dc7ff 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,11 +18,11 @@ compiler: before_install: - export CONFIGURE_ARGS="" - if command -v apt-get &>/dev/null; then sudo apt-get update -qq; fi - - if command -v apt-get &>/dev/null; then sudo apt-get install -y mlton lib-icudev; fi + - if command -v apt-get &>/dev/null; then sudo apt-get install -y mlton libicu-dev; fi - if command -v brew &>/dev/null; then brew update; fi - if command -v brew &>/dev/null; then brew uninstall libtool; fi - if command -v brew &>/dev/null; then brew install libtool; fi - - if command -v brew &>/dev/null; then brew install openssl mlton; fi + - if command -v brew &>/dev/null; then brew install openssl mlton libicu-dev; fi - if command -v brew &>/dev/null; then export CONFIGURE_ARGS="--with-openssl=/usr/local/opt/openssl"; fi script: ./autogen.sh && ./configure $CONFIGURE_ARGS && make && make test -- cgit v1.2.3 From 6ad2fd84552652fe7197a90b8a17311eedafae1b Mon Sep 17 00:00:00 2001 From: fab Date: Sat, 17 Nov 2018 22:40:03 +0000 Subject: fix package name for brew --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a36dc7ff..3ad83cbf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,7 +22,7 @@ before_install: - if command -v brew &>/dev/null; then brew update; fi - if command -v brew &>/dev/null; then brew uninstall libtool; fi - if command -v brew &>/dev/null; then brew install libtool; fi - - if command -v brew &>/dev/null; then brew install openssl mlton libicu-dev; fi + - if command -v brew &>/dev/null; then brew install openssl mlton icu4c; fi - if command -v brew &>/dev/null; then export CONFIGURE_ARGS="--with-openssl=/usr/local/opt/openssl"; fi script: ./autogen.sh && ./configure $CONFIGURE_ARGS && make && make test -- 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(-) 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 6fe0b82b4d8480c3faac955c7776e12f45e6dafa Mon Sep 17 00:00:00 2001 From: fab Date: Mon, 19 Nov 2018 21:38:25 +0000 Subject: cleanup --- tests/utf8.ur | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/tests/utf8.ur b/tests/utf8.ur index 1038a59f..468c776d 100644 --- a/tests/utf8.ur +++ b/tests/utf8.ur @@ -20,10 +20,8 @@ fun test_fn_sside [a ::: Type] (_ : eq a) (_ : show a) (f : unit -> a) (expected 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"} @@ -32,7 +30,6 @@ fun substrings () : transaction page = {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"} @@ -52,8 +49,7 @@ fun strlens () : transaction page = return {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"} - + {test_fn_both_sides (fn _ => strlen "Функциональное") 14 "strlen 13"} @@ -64,11 +60,9 @@ fun strlenGens () : transaction page = return {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"} - + {test_fn_both_sides (fn _ => strlenGe "àçá" 2) True "strlenGe 8"} @@ -87,18 +81,14 @@ fun strcats () : transaction page = in return - {test_cat_and_len 1 "" "" "" 0} - + {test_cat_and_len 1 "" "" "" 0} {test_cat_and_len 2 "aa" "bb" "aabb" 4} {test_cat_and_len 3 "" "bb" "bb" 2} {test_cat_and_len 4 "aa" "" "aa" 2} - {test_cat_and_len 5 "àà" "áá" "ààáá" 4} {test_cat_and_len 6 "" "áá" "áá" 2} {test_cat_and_len 7 "àà" "" "àà" 2} - - {test_cat_and_len 8 "函數" "ãã" "函數ãã" 4} - + {test_cat_and_len 8 "函數" "ãã" "函數ãã" 4} end @@ -145,7 +135,6 @@ fun strindexs () : transaction page = {test_fn_both_sides (fn _ => strindex "abàç" (strsub "ç" 0)) (Some 3) "strindex 5"} - fun strsindexs () : transaction page = return @@ -405,10 +394,9 @@ fun ord_and_chrs () : transaction page = {test_fn_both_sides (fn _ => chr (ord (strsub "カ" 0))) (strsub "カ" 0) "ord => chr 9"} - + table t : { Id : int, Text : string } - fun test_db () : transaction page = let val s1 = "abc" -- cgit v1.2.3 From 7165ff3ae62930d735894b8f3a55e910082800cf Mon Sep 17 00:00:00 2001 From: fab Date: Fri, 23 Nov 2018 20:42:55 +0000 Subject: test client eval vs server eval --- tests/utf8.ur | 78 ++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 58 insertions(+), 20 deletions(-) diff --git a/tests/utf8.ur b/tests/utf8.ur index 468c776d..07ac9c3d 100644 --- a/tests/utf8.ur +++ b/tests/utf8.ur @@ -19,6 +19,18 @@ fun test_fn_sside [a ::: Type] (_ : eq a) (_ : show a) (f : unit -> a) (expected
{[assert (f () = expected) "False" testname "True" ]}
+fun test_fn_cside [a ::: Type] (_ : eq a) (_ : show a) (f : unit -> a) (expected : a) (testname : string) : xbody = + +

Client side test: {[testname]}

{[r]}
+ end}> + + + fun substrings () : transaction page = return @@ -359,27 +371,40 @@ fun isxdigits () : transaction page = fun tolowers () : transaction page = - return - - {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"} - - + let + fun lower_of a _ = + tolower a + in + return + + {test_fn_both_sides (lower_of #"A") #"a" "tolower 1"} + {test_fn_both_sides (lower_of #"a") #"a" "tolower 2"} + {test_fn_both_sides (lower_of (strsub "á" 0)) (strsub "á" 0) "tolower 3"} + {test_fn_both_sides (lower_of (strsub "Á" 0)) (strsub "á" 0) "tolower 4"} + {test_fn_both_sides (lower_of #"1") #"1" "tolower 5"} + {test_fn_cside (lower_of (strsub "ß" 0)) (lower_of (strsub "ß" 0) ()) "tolower 6"} + + + end fun touppers () : transaction page = - return - - {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"} - - - + let + fun upper_of a _ = + toupper a + in + return + + {test_fn_both_sides (upper_of #"A") #"A" "toupper 1"} + {test_fn_both_sides (upper_of #"a") #"A" "toupper 2"} + {test_fn_both_sides (upper_of (strsub "á" 0)) (strsub "Á" 0) "toupper 3"} + {test_fn_both_sides (upper_of (strsub "Á" 0)) (strsub "Á" 0) "toupper 4"} + {test_fn_both_sides (upper_of #"1") #"1" "toupper 5"} + + {test_fn_cside (upper_of (strsub "ß" 0)) (upper_of (strsub "ß" 0) ()) "toupper 6"} + + + end + fun ord_and_chrs () : transaction page = return @@ -393,7 +418,19 @@ fun ord_and_chrs () : transaction page = {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"} - + + +fun test_ords () : transaction page = + let + fun ord_of c _ = + ord c + in + return + + {test_fn_cside (ord_of (strsub "a" 0)) (ord_of (strsub "a" 0) ()) "test ord 1"} + + + end table t : { Id : int, Text : string } @@ -469,6 +506,7 @@ fun index () : transaction page = tolowers touppers ord_and_chrs + test ord test_db -- 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(-) 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(-) 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(-) 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(-) 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 0d28aca9aebaf8aab32c96f8477d7121ac16b4e9 Mon Sep 17 00:00:00 2001 From: fab Date: Thu, 6 Dec 2018 21:53:26 +0000 Subject: strsindex --- lib/js/urweb.js | 32 +++++++++++++++++++++++++------- tests/utf8.ur | 25 +++++++++++++++++++++++-- 2 files changed, 48 insertions(+), 9 deletions(-) diff --git a/lib/js/urweb.js b/lib/js/urweb.js index e28446e3..2b34f8dd 100644 --- a/lib/js/urweb.js +++ b/lib/js/urweb.js @@ -1462,23 +1462,41 @@ 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 Array.from(s)[i].codePointAt(0); } +function sub(s, i) { return Array.from(s)[i]; } function suf(s, i) { return Array.from(s).slice(i).join(""); } function slen(s) { return Array.from(s).length; } function sidx(s, ch) { - var r = s.indexOf(ch); + var r = Array.from(s).indexOf(ch); if (r == -1) return null; else return r; } function ssidx(h, n) { - var r = h.indexOf(n); - if (r == -1) - return null; - else - return r; + if (n == "") return 0; + var ah = Array.from(h); + var an = Array.from(n); + var i = 0, y = 0; + var top = ah.length - an.length + 1; + if (top < 0) top = 0; + var found = true; + + for(i = 0; i < top; ++i) { + found = true; + + for (y = 0; y < an.length; ++y) { + if (ah[i + y] != an[y]) { + found = false; + break; + } + } + + if (found) + return i; + } + return null; } + function sspn(s, chs) { for (var i = 0; i < s.length; ++i) if (chs.indexOf(s.charAt(i)) != -1) diff --git a/tests/utf8.ur b/tests/utf8.ur index cf781fa9..b1507285 100644 --- a/tests/utf8.ur +++ b/tests/utf8.ur @@ -46,8 +46,29 @@ fun highencode () : transaction page = {test_fn_cside (fn _ => strlen (substring "𝌆𝌇𝌈𝌉" 1 3)) (strlen (substring "𝌆𝌇𝌈𝌉" 1 3)) "high encode - strlen of substring 1"} {test_fn_cside (fn _ => strlen (substring "𝌆𝌇𝌈𝌉" 2 2)) (strlen (substring "𝌆𝌇𝌈𝌉" 2 2)) "high encode - strlen of substring 2"} {test_fn_cside (fn _ => strlen (substring "𝌆𝌇𝌈𝌉" 3 1)) (strlen (substring "𝌆𝌇𝌈𝌉" 3 1)) "high encode - strlen of substring 3"} - - + + {test_fn_cside (fn _ => strsub "𝌆𝌇𝌈𝌉" 0) (strsub "𝌆𝌇𝌈𝌉" 0) "high encode - strsub 1"} + {test_fn_cside (fn _ => strsub "𝌆𝌇𝌈𝌉" 1) (strsub "𝌆𝌇𝌈𝌉" 1) "high encode - strsub 2"} + {test_fn_cside (fn _ => strsub "𝌆𝌇𝌈𝌉" 2) (strsub "𝌆𝌇𝌈𝌉" 2) "high encode - strsub 3"} + {test_fn_cside (fn _ => strsub "𝌆𝌇𝌈𝌉" 3) (strsub "𝌆𝌇𝌈𝌉" 3) "high encode - strsub 4"} + + {test_fn_cside (fn _ => strsuffix "𝌆𝌇𝌈𝌉" 0) (strsuffix "𝌆𝌇𝌈𝌉" 0) "high encode - strsuffix 1"} + {test_fn_cside (fn _ => strsuffix "𝌆𝌇𝌈𝌉" 1) (strsuffix "𝌆𝌇𝌈𝌉" 1) "high encode - strsuffix 2"} + {test_fn_cside (fn _ => strsuffix "𝌆𝌇𝌈𝌉" 2) (strsuffix "𝌆𝌇𝌈𝌉" 2) "high encode - strsuffix 3"} + {test_fn_cside (fn _ => strsuffix "𝌆𝌇𝌈𝌉" 3) (strsuffix "𝌆𝌇𝌈𝌉" 3) "high encode - strsuffix 4"} + + {test_fn_cside (fn _ => strchr "𝌆𝌇𝌈𝌉" #"c") (strchr "𝌆𝌇𝌈𝌉" #"c") "high encode - strchr 1"} + {test_fn_cside (fn _ => strchr "𝌆𝌇𝌈𝌉" (strsub "𝌆" 0)) (strchr "𝌆𝌇𝌈𝌉" (strsub "𝌆" 0)) "high encode - strchr 2"} + {test_fn_cside (fn _ => strchr "𝌆𝌇𝌈𝌉" (strsub "𝌇" 0)) (strchr "𝌆𝌇𝌈𝌉" (strsub "𝌇" 0)) "high encode - strchr 3"} + {test_fn_cside (fn _ => strchr "𝌆𝌇𝌈𝌉" (strsub "𝌈" 0)) (strchr "𝌆𝌇𝌈𝌉" (strsub "𝌈" 0)) "high encode - strchr 4"} + {test_fn_cside (fn _ => strchr "𝌆𝌇𝌈𝌉" (strsub "𝌉" 0)) (strchr "𝌆𝌇𝌈𝌉" (strsub "𝌉" 0)) "high encode - strchr 5"} + + {test_fn_cside (fn _ => strindex "𝌆𝌇𝌈𝌉" #"c") (strindex "𝌆𝌇𝌈𝌉" #"c") "high encode - strindex 1"} + {test_fn_cside (fn _ => strindex "𝌆𝌇𝌈𝌉" (strsub "𝌆" 0)) (strindex "𝌆𝌇𝌈𝌉" (strsub "𝌆" 0)) "high encode - strindex 2"} + {test_fn_cside (fn _ => strindex "𝌆𝌇𝌈𝌉" (strsub "𝌇" 0)) (strindex "𝌆𝌇𝌈𝌉" (strsub "𝌇" 0)) "high encode - strindex 3"} + {test_fn_cside (fn _ => strindex "𝌆𝌇𝌈𝌉" (strsub "𝌈" 0)) (strindex "𝌆𝌇𝌈𝌉" (strsub "𝌈" 0)) "high encode - strindex 4"} + {test_fn_cside (fn _ => strindex "𝌆𝌇𝌈𝌉" (strsub "𝌉" 0)) (strindex "𝌆𝌇𝌈𝌉" (strsub "𝌉" 0)) "high encode - strindex 5"} + fun substrings () : transaction page = -- cgit v1.2.3 From 8e998f7d96d3236e182ea54cc077f87538651af3 Mon Sep 17 00:00:00 2001 From: fab Date: Thu, 6 Dec 2018 21:59:47 +0000 Subject: ord --- lib/js/urweb.js | 2 +- tests/utf8.ur | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/lib/js/urweb.js b/lib/js/urweb.js index 2b34f8dd..18d47847 100644 --- a/lib/js/urweb.js +++ b/lib/js/urweb.js @@ -35,7 +35,7 @@ function isAlnum(c) { return isAlpha(c) || isDigit(c); } function isBlank(c) { return c == ' ' || c == '\t'; } function isSpace(c) { return isBlank(c) || c == '\r' || c == '\n'; } function isXdigit(c) { return isDigit(c) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'); } -function ord(c) { return c.charCodeAt(0); } +function ord(c) { return c.codePointAt(0); } function isPrint(c) { return ord(c) > 31 && ord(c) != 127; } function toLower(c) { return c.toLowerCase(); } function toUpper(c) { diff --git a/tests/utf8.ur b/tests/utf8.ur index b1507285..b519b615 100644 --- a/tests/utf8.ur +++ b/tests/utf8.ur @@ -68,6 +68,12 @@ fun highencode () : transaction page = {test_fn_cside (fn _ => strindex "𝌆𝌇𝌈𝌉" (strsub "𝌇" 0)) (strindex "𝌆𝌇𝌈𝌉" (strsub "𝌇" 0)) "high encode - strindex 3"} {test_fn_cside (fn _ => strindex "𝌆𝌇𝌈𝌉" (strsub "𝌈" 0)) (strindex "𝌆𝌇𝌈𝌉" (strsub "𝌈" 0)) "high encode - strindex 4"} {test_fn_cside (fn _ => strindex "𝌆𝌇𝌈𝌉" (strsub "𝌉" 0)) (strindex "𝌆𝌇𝌈𝌉" (strsub "𝌉" 0)) "high encode - strindex 5"} + + {test_fn_cside (fn _ => ord (strsub "𝌆𝌇𝌈𝌉" 0)) (ord (strsub "𝌆𝌇𝌈𝌉" 0)) "high encode - ord 1"} + {test_fn_cside (fn _ => ord (strsub "𝌆𝌇𝌈𝌉" 1)) (ord (strsub "𝌆𝌇𝌈𝌉" 1)) "high encode - ord 2"} + {test_fn_cside (fn _ => ord (strsub "𝌆𝌇𝌈𝌉" 2)) (ord (strsub "𝌆𝌇𝌈𝌉" 2)) "high encode - ord 3"} + {test_fn_cside (fn _ => ord (strsub "𝌆𝌇𝌈𝌉" 3)) (ord (strsub "𝌆𝌇𝌈𝌉" 3)) "high encode - ord 4"} + @@ -471,6 +477,11 @@ fun test_ords () : transaction page = return {test_fn_cside (ord_of (strsub "a" 0)) (ord_of (strsub "a" 0) ()) "test ord 1"} + {test_fn_cside (ord_of (strsub "á" 0)) (ord_of (strsub "á" 0) ()) "test ord 2"} + {test_fn_cside (ord_of (strsub "5" 0)) (ord_of (strsub "5" 0) ()) "test ord 3"} + {test_fn_cside (ord_of (strsub "が" 0)) (ord_of (strsub "が" 0) ()) "test ord 4"} + {test_fn_cside (ord_of (strsub "漢" 0)) (ord_of (strsub "漢" 0) ()) "test ord 5"} + {test_fn_cside (ord_of (strsub "カ" 0)) (ord_of (strsub "カ" 0) ()) "test ord 6"} end -- cgit v1.2.3 From 3795cd7e0182bd0845024373a31f97ee200597da Mon Sep 17 00:00:00 2001 From: fab Date: Thu, 6 Dec 2018 22:24:13 +0000 Subject: strsub, strcspn, strsindex --- lib/js/urweb.js | 9 ++++++--- tests/utf8.ur | 22 ++++++++++++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/lib/js/urweb.js b/lib/js/urweb.js index 18d47847..f41d7240 100644 --- a/lib/js/urweb.js +++ b/lib/js/urweb.js @@ -1498,11 +1498,14 @@ function ssidx(h, n) { } function sspn(s, chs) { - for (var i = 0; i < s.length; ++i) - if (chs.indexOf(s.charAt(i)) != -1) + var s2 = Array.from(s); + var chs2 = Array.from(chs); + + for (var i = 0; i < s2.length; ++i) + if (chs2.indexOf(s2[i]) != -1) return i; - return s.length; + return s2.length; } function schr(s, ch) { var r = s.indexOf(ch); diff --git a/tests/utf8.ur b/tests/utf8.ur index b519b615..c7aefd79 100644 --- a/tests/utf8.ur +++ b/tests/utf8.ur @@ -69,11 +69,33 @@ fun highencode () : transaction page = {test_fn_cside (fn _ => strindex "𝌆𝌇𝌈𝌉" (strsub "𝌈" 0)) (strindex "𝌆𝌇𝌈𝌉" (strsub "𝌈" 0)) "high encode - strindex 4"} {test_fn_cside (fn _ => strindex "𝌆𝌇𝌈𝌉" (strsub "𝌉" 0)) (strindex "𝌆𝌇𝌈𝌉" (strsub "𝌉" 0)) "high encode - strindex 5"} + {test_fn_cside (fn _ => strsindex "𝌆𝌇𝌈𝌉" "") (strsindex "𝌆𝌇𝌈𝌉" "") "high encode - strsindex 1"} + {test_fn_cside (fn _ => strsindex "𝌆𝌇𝌈𝌉" "𝌆𝌇𝌈𝌉") (strsindex "𝌆𝌇𝌈𝌉" "𝌆𝌇𝌈𝌉") "high encode - strsindex 2"} + {test_fn_cside (fn _ => strsindex "𝌆𝌇𝌈𝌉" "𝌆𝌇𝌈c") (strsindex "𝌆𝌇𝌈𝌉" "𝌆𝌇𝌈c") "high encode - strsindex 3"} + {test_fn_cside (fn _ => strsindex "𝌆𝌇𝌈𝌉" "𝌇𝌈𝌉") (strsindex "𝌆𝌇𝌈𝌉" "𝌇𝌈𝌉") "high encode - strsindex 4"} + {test_fn_cside (fn _ => strsindex "𝌆𝌇𝌈𝌉" "𝌇𝌈c") (strsindex "𝌆𝌇𝌈𝌉" "𝌇𝌈c") "high encode - strsindex 5"} + {test_fn_cside (fn _ => strsindex "𝌆𝌇𝌈𝌉" "𝌈𝌉") (strsindex "𝌆𝌇𝌈𝌉" "𝌈𝌉") "high encode - strsindex 6"} + {test_fn_cside (fn _ => strsindex "𝌆𝌇𝌈𝌉" "𝌈c") (strsindex "𝌆𝌇𝌈𝌉" "𝌈c") "high encode - strsindex 7"} + {test_fn_cside (fn _ => strsindex "𝌆𝌇𝌈𝌉" "𝌉") (strsindex "𝌆𝌇𝌈𝌉" "𝌉") "high encode - strsindex 8"} + {test_fn_cside (fn _ => strsindex "𝌆𝌇𝌈𝌉" "c") (strsindex "𝌆𝌇𝌈𝌉" "c") "high encode - strsindex 9"} + + {test_fn_cside (fn _ => strcspn "𝌆𝌇𝌈𝌉" "") (strcspn "𝌆𝌇𝌈𝌉" "") "high encode - strcspn 1"} + {test_fn_cside (fn _ => strcspn "𝌆𝌇𝌈𝌉" "𝌆𝌇𝌈𝌉") (strcspn "𝌆𝌇𝌈𝌉" "𝌆𝌇𝌈𝌉") "high encode - strcspn 2"} + {test_fn_cside (fn _ => strcspn "𝌆𝌇𝌈𝌉" "𝌆") (strcspn "𝌆𝌇𝌈𝌉" "𝌆") "high encode - strcspn 3"} + {test_fn_cside (fn _ => strcspn "𝌆𝌇𝌈𝌉" "𝌇𝌈𝌉") (strcspn "𝌆𝌇𝌈𝌉" "𝌇𝌈𝌉") "high encode - strcspn 4"} + {test_fn_cside (fn _ => strcspn "𝌆𝌇𝌈𝌉" "𝌈𝌉") (strcspn "𝌆𝌇𝌈𝌉" "𝌈𝌉") "high encode - strcspn 5"} + {test_fn_cside (fn _ => strcspn "𝌆𝌇𝌈𝌉" "𝌉") (strcspn "𝌆𝌇𝌈𝌉" "𝌉") "high encode - strcspn 6"} + {test_fn_cside (fn _ => ord (strsub "𝌆𝌇𝌈𝌉" 0)) (ord (strsub "𝌆𝌇𝌈𝌉" 0)) "high encode - ord 1"} {test_fn_cside (fn _ => ord (strsub "𝌆𝌇𝌈𝌉" 1)) (ord (strsub "𝌆𝌇𝌈𝌉" 1)) "high encode - ord 2"} {test_fn_cside (fn _ => ord (strsub "𝌆𝌇𝌈𝌉" 2)) (ord (strsub "𝌆𝌇𝌈𝌉" 2)) "high encode - ord 3"} {test_fn_cside (fn _ => ord (strsub "𝌆𝌇𝌈𝌉" 3)) (ord (strsub "𝌆𝌇𝌈𝌉" 3)) "high encode - ord 4"} + {test_fn_cside (fn _ => show (strsub "𝌆𝌇𝌈𝌉" 0)) (show (strsub "𝌆𝌇𝌈𝌉" 0)) "high encode - show 1"} + {test_fn_cside (fn _ => show (strsub "𝌆𝌇𝌈𝌉" 1)) (show (strsub "𝌆𝌇𝌈𝌉" 1)) "high encode - show 2"} + {test_fn_cside (fn _ => show (strsub "𝌆𝌇𝌈𝌉" 2)) (show (strsub "𝌆𝌇𝌈𝌉" 2)) "high encode - show 3"} + {test_fn_cside (fn _ => show (strsub "𝌆𝌇𝌈𝌉" 3)) (show (strsub "𝌆𝌇𝌈𝌉" 3)) "high encode - show 4"} + -- cgit v1.2.3 From 3e5ee79bbd540851bb879f5c81ef0186ce91078e Mon Sep 17 00:00:00 2001 From: fab Date: Sat, 8 Dec 2018 22:03:56 +0000 Subject: patching toLower and toUpper to provide consistent results in server side and client side --- lib/js/urweb.js | 118 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 114 insertions(+), 4 deletions(-) diff --git a/lib/js/urweb.js b/lib/js/urweb.js index f41d7240..19f708ca 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.toLowerCase() == c && c != c.toUpperCase(); } -function isUpper(c) { return c.toUpperCase() == c && c != c.toLowerCase(); } +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 isDigit(c) { return c >= '0' && c <= '9'; } function isAlnum(c) { return isAlpha(c) || isDigit(c); } @@ -37,9 +37,119 @@ 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 toLower(c) { return c.toLowerCase(); } + +function toLower(c) { + var cp = ord(c); + if (cp == 304) + return chr(105); + else if (cp >= 7312 && cp <= 7354) + return c; + else if (cp >= 7357 && cp <= 7359) + return c; + else if (cp == 42936) + return c; + else if (cp >= 93760 && cp <= 93791) + return c; + return c.toLowerCase(); +} + function toUpper(c) { - if (ord(c) == 223) + var cp = ord(c); + if (cp == 223) + return c; + else if (cp == 329) + return c; + else if (cp == 496) + return c; + else if (cp == 912) + return c; + else if (cp == 944) + return c; + else if (cp == 1415) + return c; + else if (cp >= 4304 && cp <= 4346) + return c; + else if (cp >= 4349 && cp <= 4351) + return c; + else if (cp >= 7830 && cp <= 7834) + return c; + else if (cp == 8016) + return c; + else if (cp == 8018) + return c; + else if (cp == 8020) + return c; + else if (cp == 8022) + return c; + else if (cp >= 8064 && cp <= 8071) + return chr(cp + 8) + else if (cp >= 8072 && cp <= 8079) + return c; + else if (cp >= 8080 && cp <= 8087) + return chr(cp + 8); + else if (cp >= 8088 && cp <= 8095) + return c; + else if (cp >= 8096 && cp <= 8103) + return chr(cp + 8) + else if (cp >= 8104 && cp <= 8111) + return c; + else if (cp == 8114) + return c; + else if (cp == 8115) + return chr(8124); + else if (cp == 8116) + return c; + else if (cp == 8118) + return c; + else if (cp == 8119) + return c; + else if (cp == 8124) + return c; + else if (cp == 8130) + return c; + else if (cp == 8131) + return chr(8140); + else if (cp == 8132) + return c; + else if (cp == 8134) + return c; + else if (cp == 8135) + return c; + else if (cp == 8140) + return c; + else if (cp == 8146) + return c; + else if (cp == 8147) + return c; + else if (cp == 8150) + return c; + else if (cp == 8151) + return c; + else if (cp >= 8162 && cp <= 8164) + return c; + else if (cp == 8166) + return c; + else if (cp == 8167) + return c; + else if (cp == 8178) + return c; + else if (cp == 8179) + return chr(8188); + else if (cp == 8180) + return c; + else if (cp == 8182) + return c; + else if (cp == 8183) + return c; + else if (cp == 8188) + return c; + else if (cp == 42937) + return c; + else if (cp >= 64256 && cp <= 64262) + return c; + else if (cp >= 64275 && cp <= 64279) + return c; + else if (cp >= 93792 && cp <= 93823) return c; else return c.toUpperCase(); -- cgit v1.2.3 From 847ba6fecb19b7cc694355b87cb3be7183ca1287 Mon Sep 17 00:00:00 2001 From: fab Date: Sat, 8 Dec 2018 23:12:33 +0000 Subject: patch isDigit --- lib/js/urweb.js | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 116 insertions(+), 1 deletion(-) diff --git a/lib/js/urweb.js b/lib/js/urweb.js index 19f708ca..a10751e3 100644 --- a/lib/js/urweb.js +++ b/lib/js/urweb.js @@ -30,7 +30,122 @@ function le(x, y) { return x <= y; } 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 isDigit(c) { return c >= '0' && c <= '9'; } +function isDigit(c) { + if (c >= '0' && c <= '9') + return true; + + var cp = ord(c); + if (cp >= 1632 && cp <= 1641) + return true; + else if (cp >= 1776 && cp <= 1785) + return true; + else if (cp >= 1984 && cp <= 1993) + return true; + else if (cp >= 2406 && cp <= 2415) + return true; + else if (cp >= 2534 && cp <= 2543) + return true; + else if (cp >= 2662 && cp <= 2671) + return true; + else if (cp >= 2790 && cp <= 2799) + return true; + else if (cp >= 2918 && cp <= 2927) + return true; + else if (cp >= 3046 && cp <= 3055) + return true; + else if (cp >= 3174 && cp <= 3183) + return true; + else if (cp >= 3302 && cp <= 3311) + return true; + else if (cp >= 3430 && cp <= 3439) + return true; + else if (cp >= 3558 && cp <= 3567) + return true; + else if (cp >= 3664 && cp <= 3673) + return true; + else if (cp >= 3792 && cp <= 3801) + return true; + else if (cp >= 3872 && cp <= 3881) + return true; + else if (cp >= 4160 && cp <= 4169) + return true; + else if (cp >= 4240 && cp <= 4249) + return true; + else if (cp >= 6112 && cp <= 6121) + return true; + else if (cp >= 6160 && cp <= 6169) + return true; + else if (cp >= 6470 && cp <= 6479) + return true; + else if (cp >= 6608 && cp <= 6617) + return true; + else if (cp >= 6784 && cp <= 6793) + return true; + else if (cp >= 6800 && cp <= 6809) + return true; + else if (cp >= 6992 && cp <= 7001) + return true; + else if (cp >= 7088 && cp <= 7097) + return true; + else if (cp >= 7232 && cp <= 7241) + return true; + else if (cp >= 7248 && cp <= 7257) + return true; + else if (cp >= 42528 && cp <= 42537) + return true; + else if (cp >= 43216 && cp <= 43225) + return true; + else if (cp >= 43264 && cp <= 43273) + return true; + else if (cp >= 43472 && cp <= 43481) + return true; + else if (cp >= 43504 && cp <= 43513) + return true; + else if (cp >= 43600 && cp <= 43609) + return true; + else if (cp >= 44016 && cp <= 44025) + return true; + else if (cp >= 65296 && cp <= 65305) + return true; + else if (cp >= 66720 && cp <= 66729) + return true; + else if (cp >= 69734 && cp <= 69743) + return true; + else if (cp >= 69872 && cp <= 69881) + return true; + else if (cp >= 69942 && cp <= 69951) + return true; + else if (cp >= 70096 && cp <= 70105) + return true; + else if (cp >= 70384 && cp <= 70393) + return true; + else if (cp >= 70736 && cp <= 70745) + return true; + else if (cp >= 70864 && cp <= 70873) + return true; + else if (cp >= 71248 && cp <= 71257) + return true; + else if (cp >= 71360 && cp <= 71369) + return true; + else if (cp >= 71472 && cp <= 71481) + return true; + else if (cp >= 71904 && cp <= 71913) + return true; + else if (cp >= 72784 && cp <= 72793) + return true; + else if (cp >= 73040 && cp <= 73049) + return true; + else if (cp >= 92768 && cp <= 92777) + return true; + else if (cp >= 93008 && cp <= 93017) + return true; + else if (cp >= 120782 && cp <= 120831) + return true; + else 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'; } -- cgit v1.2.3 From f062b43f613ce0e6596efc35fc6e888c9a1f5495 Mon Sep 17 00:00:00 2001 From: fab Date: Sat, 8 Dec 2018 23:13:56 +0000 Subject: just to make sure there are no issues --- lib/js/urweb.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/js/urweb.js b/lib/js/urweb.js index a10751e3..05ee2a17 100644 --- a/lib/js/urweb.js +++ b/lib/js/urweb.js @@ -31,11 +31,10 @@ 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 isDigit(c) { - if (c >= '0' && c <= '9') - return true; - var cp = ord(c); - if (cp >= 1632 && cp <= 1641) + if (cp >= 48 && c <= 57) + return true; + else if (cp >= 1632 && cp <= 1641) return true; else if (cp >= 1776 && cp <= 1785) return true; -- 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(-) 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(-) 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(-) 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 From db41db44f8693d6d1b740eb0b55ef84a4245b576 Mon Sep 17 00:00:00 2001 From: fab Date: Wed, 12 Dec 2018 21:29:05 +0000 Subject: tidy unit tests --- tests/utf8.py | 112 ++++++++++++++++++++++++++++++++-------------------------- tests/utf8.ur | 20 +++-------- 2 files changed, 66 insertions(+), 66 deletions(-) diff --git a/tests/utf8.py b/tests/utf8.py index ac8df5c3..6036fa12 100644 --- a/tests/utf8.py +++ b/tests/utf8.py @@ -2,109 +2,119 @@ import unittest import base class Suite(base.Base): - def test_99(self): + + def no_falses(self, name): + self.start('Utf8/' + name) + + elems = self.driver.find_elements_by_xpath('//pre') + + self.assertNotEqual(0, len(elems)) + for e in elems: + self.assertEqual("True", e.text) + + def test_1(self): """Test case: substring (1)""" - self.start('Utf8/substrings') - - def test_98(self): + self.no_falses('substrings') + + def test_2(self): """Test case: strlen (2)""" - self.start('Utf8/strlens') + self.no_falses('strlens') - def test_97(self): + def test_3(self): """Test case: strlenGe (3)""" - self.start('Utf8/strlenGens') + self.no_falses('strlenGens') - def test_96(self): + def test_4(self): """Test case: strcat (4)""" - self.start('Utf8/strcats') + self.no_falses('strcats') - def test_95(self): + def test_5(self): """Test case: strsub (5)""" - self.start('Utf8/strsubs') + self.no_falses('strsubs') - def test_94(self): + def test_6(self): """Test case: strsuffix (6)""" - self.start('Utf8/strsuffixs') + self.no_falses('strsuffixs') - def test_93(self): + def test_7(self): """Test case: strchr (7)""" - self.start('Utf8/strchrs') + self.no_falses('strchrs') - def test_92(self): + def test_8(self): """Test case: strindex (8)""" - self.start('Utf8/strindexs') + self.no_falses('strindexs') - def test_91(self): + def test_9(self): """Test case: strindex (9)""" - self.start('Utf8/strsindexs') + self.no_falses('strsindexs') - def test_90(self): + def test_10(self): """Test case: strcspn (10)""" - self.start('Utf8/strcspns') + self.no_falses('strcspns') - def test_89(self): + def test_11(self): """Test case: str1 (11)""" - self.start('Utf8/str1s') + self.no_falses('str1s') - def test_88(self): + def test_12(self): """Test case: isalnum (12)""" - self.start('Utf8/isalnums') + self.no_falses('isalnums') def test_13(self): """Test case: isalpha (13)""" - self.start('Utf8/isalphas') + self.no_falses('isalphas') def test_14(self): """Test case: isblank (14)""" - self.start('Utf8/isblanks') + self.no_falses('isblanks') def test_15(self): """Test case: iscntrl (15)""" - self.start('Utf8/iscntrls') + self.no_falses('iscntrls') def test_16(self): """Test case: isdigit (16)""" - self.start('Utf8/isdigits') + self.no_falses('isdigits') def test_17(self): """Test case: isgraph (17)""" - self.start('Utf8/isgraphs') + self.no_falses('isgraphs') def test_18(self): """Test case: islower (18)""" - self.start('Utf8/islowers') + self.no_falses('islowers') def test_19(self): """Test case: isprint (19)""" - self.start('Utf8/isprints') + self.no_falses('isprints') def test_20(self): """Test case: ispunct (20)""" - self.start('Utf8/ispuncts') + self.no_falses('ispuncts') def test_21(self): """Test case: isspace (21)""" - self.start('Utf8/isspaces') + self.no_falses('isspaces') def test_22(self): """Test case: isupper (22)""" - self.start('Utf8/isuppers') + self.no_falses('isuppers') def test_23(self): """Test case: isxdigit (23)""" - self.start('Utf8/isxdigits') + self.no_falses('isxdigits') def test_24(self): """Test case: toupper (24)""" - self.start('Utf8/touppers') + self.no_falses('touppers') def test_25(self): """Test case: ord (25)""" - self.start('Utf8/ord_and_chrs') + self.no_falses('ord_and_chrs') def test_26 (self): """Test case: test_db (26) """ - self.start('Utf8/test_db') + self.no_falses('test_db') def full_test (self, name): @@ -117,46 +127,48 @@ class Suite(base.Base): i = i + gap - def test_1 (self): + def test_89 (self): """Test case: ftTolower """ self.full_test("ftTolower") - def test_2 (self): + def test_90 (self): """Test case: ftToupper """ self.full_test("ftToupper") - def test_3 (self): + def test_91 (self): """Test case: ftIsalpha """ self.full_test("ftIsalpha") - def test_4 (self): + def test_92 (self): """Test case: ftIsdigit """ self.full_test("ftIsdigit") - def test_5 (self): + def test_93 (self): """Test case: ftIsalnum """ self.full_test("ftIsalnum") - def test_6 (self): + def test_94 (self): """Test case: ftIsspace """ self.full_test("ftIsspace") - def test_7 (self): + def test_95 (self): """Test case: ftIsblank """ self.full_test("ftIsblank") - def test_8 (self): + def test_96 (self): """Test case: ftIsprint """ self.full_test("ftIsprint") - def test_9 (self): + def test_97 (self): """Test case: ftIsxdigit """ self.full_test("ftIsxdigit") - def test_10 (self): + def test_98 (self): """Test case: ftIsupper """ self.full_test("ftIsupper") - def test_11 (self): + def test_99 (self): """Test case: ftIslower """ self.full_test("ftIslower") + ''' + ''' diff --git a/tests/utf8.ur b/tests/utf8.ur index 777bb141..4a89c22b 100644 --- a/tests/utf8.ur +++ b/tests/utf8.ur @@ -11,32 +11,20 @@ fun from_m_upto_n f m n = 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}> +
{[show (f () = expected)]}
+

Client side test: {[testname]}

{[show (f () = expected)]}
}> 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" ]}
+
{[show (f () = expected)]}
fun test_fn_cside [a ::: Type] (_ : eq a) (_ : show a) (f : unit -> a) (expected : a) (testname : string) : xbody = -

Client side test: {[testname]}

{[r]}
- end}> +

Client side test: {[testname]}

{[show (f () = expected)]}
}>
-- cgit v1.2.3 From ffab923e07b7fa66c28490c8791ec538b0f34fa2 Mon Sep 17 00:00:00 2001 From: fab Date: Mon, 17 Dec 2018 21:06:08 +0000 Subject: osx troubleshooting --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 3ad83cbf..fa800b3c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,6 +23,8 @@ before_install: - if command -v brew &>/dev/null; then brew uninstall libtool; fi - if command -v brew &>/dev/null; then brew install libtool; fi - if command -v brew &>/dev/null; then brew install openssl mlton icu4c; fi + - if command -v brew &>/dev/null; then brew ls --verbose icu4c; fi - if command -v brew &>/dev/null; then export CONFIGURE_ARGS="--with-openssl=/usr/local/opt/openssl"; fi + script: ./autogen.sh && ./configure $CONFIGURE_ARGS && make && make test -- cgit v1.2.3 From d036b4badacc7e683fa5e3ba79570bc560c47aa6 Mon Sep 17 00:00:00 2001 From: fab Date: Mon, 17 Dec 2018 21:18:43 +0000 Subject: test 1 --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index fa800b3c..eaeefd7e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,11 +1,9 @@ language: c os: - - linux - osx compiler: - - clang - gcc # when https://github.com/travis-ci/apt-package-whitelist/issues/792 is closed, use the container-based infrastructure @@ -24,6 +22,8 @@ before_install: - if command -v brew &>/dev/null; then brew install libtool; fi - if command -v brew &>/dev/null; then brew install openssl mlton icu4c; fi - if command -v brew &>/dev/null; then brew ls --verbose icu4c; fi + - if command -v brew &>/dev/null; then brew --prefix icu4c; fi + - if command -v brew &>/dev/null; then brew unlink icu4c && brew link icu4c; fi - if command -v brew &>/dev/null; then export CONFIGURE_ARGS="--with-openssl=/usr/local/opt/openssl"; fi -- cgit v1.2.3 From 3f70998a08b5169b3846537a8b6114465fca2b1a Mon Sep 17 00:00:00 2001 From: fab Date: Mon, 17 Dec 2018 21:41:10 +0000 Subject: test2 --- .travis.yml | 4 +--- configure.ac | 1 + src/c/Makefile.am | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index eaeefd7e..2c798801 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,9 +21,7 @@ before_install: - if command -v brew &>/dev/null; then brew uninstall libtool; fi - if command -v brew &>/dev/null; then brew install libtool; fi - if command -v brew &>/dev/null; then brew install openssl mlton icu4c; fi - - if command -v brew &>/dev/null; then brew ls --verbose icu4c; fi - - if command -v brew &>/dev/null; then brew --prefix icu4c; fi - - if command -v brew &>/dev/null; then brew unlink icu4c && brew link icu4c; fi + - if command -v brew &>/dev/null; then export ICU_INCLUDES=`brew --prefix icu4c`/include; fi - if command -v brew &>/dev/null; then export CONFIGURE_ARGS="--with-openssl=/usr/local/opt/openssl"; fi diff --git a/configure.ac b/configure.ac index 54eac40e..bd52aa4c 100644 --- a/configure.ac +++ b/configure.ac @@ -125,6 +125,7 @@ AC_SUBST(SQHEADER) AC_SUBST(VERSION) AC_SUBST(PTHREAD_CFLAGS) AC_SUBST(PTHREAD_LIBS) +AC_SUBST(ICU_INCLUDES) AC_CONFIG_FILES([ Makefile diff --git a/src/c/Makefile.am b/src/c/Makefile.am index 96c1d92f..8a2a81ec 100644 --- a/src/c/Makefile.am +++ b/src/c/Makefile.am @@ -6,7 +6,7 @@ liburweb_cgi_la_SOURCES = cgi.c liburweb_fastcgi_la_SOURCES = fastcgi.c fastcgi.h liburweb_static_la_SOURCES = static.c -AM_CPPFLAGS = -I$(srcdir)/../../include/urweb $(OPENSSL_INCLUDES) +AM_CPPFLAGS = -I$(srcdir)/../../include/urweb $(OPENSSL_INCLUDES) $(ICU_INCLUDES) AM_CFLAGS = -Wall -Wunused-parameter -Werror -Wno-format-security -Wno-deprecated-declarations -U_FORTIFY_SOURCE $(PTHREAD_CFLAGS) liburweb_la_LDFLAGS = $(AM_LDFLAGS) $(OPENSSL_LDFLAGS) \ -export-symbols-regex '^(client_pruner|pthread_create_big|strcmp_nullsafe|uw_.*)' \ -- cgit v1.2.3 From e45f51c67dcba21af1036468b84bf6fd634835e9 Mon Sep 17 00:00:00 2001 From: fab Date: Mon, 17 Dec 2018 21:52:11 +0000 Subject: test 3 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 2c798801..b5a213c5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,7 +21,7 @@ before_install: - if command -v brew &>/dev/null; then brew uninstall libtool; fi - if command -v brew &>/dev/null; then brew install libtool; fi - if command -v brew &>/dev/null; then brew install openssl mlton icu4c; fi - - if command -v brew &>/dev/null; then export ICU_INCLUDES=`brew --prefix icu4c`/include; fi + - if command -v brew &>/dev/null; then export ICU_INCLUDES=-I"`brew --prefix icu4c`/include"; fi - if command -v brew &>/dev/null; then export CONFIGURE_ARGS="--with-openssl=/usr/local/opt/openssl"; fi -- cgit v1.2.3 From ea79cb9fc1cfbb1418a8c4139200ba4b21dc2318 Mon Sep 17 00:00:00 2001 From: fab Date: Mon, 17 Dec 2018 22:05:18 +0000 Subject: test 4 --- .travis.yml | 3 +++ src/c/Makefile.am | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index b5a213c5..1becfb0f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,7 @@ language: c os: - osx + - linux compiler: - gcc @@ -21,7 +22,9 @@ before_install: - if command -v brew &>/dev/null; then brew uninstall libtool; fi - if command -v brew &>/dev/null; then brew install libtool; fi - if command -v brew &>/dev/null; then brew install openssl mlton icu4c; fi + - if command -v brew &>/dev/null; then brew ls --verbose icu4c; fi - if command -v brew &>/dev/null; then export ICU_INCLUDES=-I"`brew --prefix icu4c`/include"; fi + - if command -v brew &>/dev/null; then export ICU_LIBS=-L"`brew --prefix icu4c`/lib"; fi - if command -v brew &>/dev/null; then export CONFIGURE_ARGS="--with-openssl=/usr/local/opt/openssl"; fi diff --git a/src/c/Makefile.am b/src/c/Makefile.am index 8a2a81ec..819dd2c2 100644 --- a/src/c/Makefile.am +++ b/src/c/Makefile.am @@ -11,7 +11,7 @@ AM_CFLAGS = -Wall -Wunused-parameter -Werror -Wno-format-security -Wno-deprecate liburweb_la_LDFLAGS = $(AM_LDFLAGS) $(OPENSSL_LDFLAGS) \ -export-symbols-regex '^(client_pruner|pthread_create_big|strcmp_nullsafe|uw_.*)' \ -version-info 1:0:0 -liburweb_la_LIBADD = $(PTHREAD_LIBS) -lm $(OPENSSL_LIBS) -licui18n -licuuc -licudata +liburweb_la_LIBADD = $(PTHREAD_LIBS) -lm $(OPENSSL_LIBS) $(ICU_LIBS) -licui18n -licuuc -licudata liburweb_http_la_LIBADD = liburweb.la liburweb_http_la_LDFLAGS = -export-symbols-regex '^(main|uw_.*)' \ -version-info 1:0:0 -- cgit v1.2.3 From 757e40719735a45085343e90b53674b9b276b5cb Mon Sep 17 00:00:00 2001 From: fab Date: Mon, 17 Dec 2018 22:25:59 +0000 Subject: test 5 --- configure.ac | 1 + src/compiler.sml | 4 ++-- src/config.sig | 3 +++ src/config.sml.in | 3 +++ src/settings.sig | 1 + src/settings.sml | 2 +- 6 files changed, 11 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index bd52aa4c..d6b1c98f 100644 --- a/configure.ac +++ b/configure.ac @@ -126,6 +126,7 @@ AC_SUBST(VERSION) AC_SUBST(PTHREAD_CFLAGS) AC_SUBST(PTHREAD_LIBS) AC_SUBST(ICU_INCLUDES) +AC_SUBST(ICU_LIBS) AC_CONFIG_FILES([ Makefile diff --git a/src/compiler.sml b/src/compiler.sml index 9ee88c9b..06615bcf 100644 --- a/src/compiler.sml +++ b/src/compiler.sml @@ -1585,9 +1585,9 @@ fun compileC {cname, oname, ename, libs, profile, debug, linker, link = link'} = val proto = Settings.currentProtocol () val lib = if Settings.getBootLinking () then - !Settings.configLib ^ "/" ^ #linkStatic proto ^ " " ^ !Settings.configLib ^ "/liburweb.a -licui18n -licuuc -licudata" + !Settings.configLib ^ "/" ^ #linkStatic proto ^ " " ^ !Settings.configLib ^ "/liburweb.a " ^ !Settings.configIcuLibs ^ " -licui18n -licuuc -licudata" else if Settings.getStaticLinking () then - " -static " ^ !Settings.configLib ^ "/" ^ #linkStatic proto ^ " " ^ !Settings.configLib ^ "/liburweb.a -licui18n -licuuc -licudata" + " -static " ^ !Settings.configLib ^ "/" ^ #linkStatic proto ^ " " ^ !Settings.configLib ^ "/liburweb.a " ^ !Settings.configIcuLibs ^ " -licui18n -licuuc -licudata" else "-L" ^ !Settings.configLib ^ " " ^ #linkDynamic proto ^ " -lurweb" diff --git a/src/config.sig b/src/config.sig index a3ad7d76..be72a8cc 100644 --- a/src/config.sig +++ b/src/config.sig @@ -20,4 +20,7 @@ signature CONFIG = sig val pthreadCflags : string val pthreadLibs : string + + val icuIncludes : string + val icuLibs : string end diff --git a/src/config.sml.in b/src/config.sml.in index ebcdb7b6..2d12e28d 100644 --- a/src/config.sml.in +++ b/src/config.sml.in @@ -28,6 +28,9 @@ val pgheader = "@PGHEADER@" val msheader = "@MSHEADER@" val sqheader = "@SQHEADER@" +val icuIncludes = "@ICU_INCLUDES@" +val icuLibs = "@ICU_LIBS@" + val versionNumber = "@VERSION@" val versionString = "The Ur/Web compiler, version " ^ versionNumber diff --git a/src/settings.sig b/src/settings.sig index 986d6ed7..22dc80a2 100644 --- a/src/settings.sig +++ b/src/settings.sig @@ -37,6 +37,7 @@ signature SETTINGS = sig val configSrcLib : string ref val configInclude : string ref val configSitelisp : string ref + val configIcuLibs : string ref val libUr : unit -> string val libC : unit -> string diff --git a/src/settings.sml b/src/settings.sml index cfbe98a5..8ae2d377 100644 --- a/src/settings.sml +++ b/src/settings.sml @@ -32,7 +32,7 @@ val configLib = ref Config.lib val configSrcLib = ref Config.srclib val configInclude = ref Config.includ val configSitelisp = ref Config.sitelisp - +val configIcuLibs = ref Config.icuLibs val configCCompiler = ref Config.ccompiler fun getCCompiler () = !configCCompiler -- cgit v1.2.3 From 2d699b85cfb3f137e8963ad9a355918e40b39d62 Mon Sep 17 00:00:00 2001 From: fab Date: Mon, 17 Dec 2018 22:41:16 +0000 Subject: test 6 --- src/compiler.sml | 4 ++-- src/settings.sig | 1 + src/settings.sml | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/compiler.sml b/src/compiler.sml index 06615bcf..1f77a821 100644 --- a/src/compiler.sml +++ b/src/compiler.sml @@ -1585,9 +1585,9 @@ fun compileC {cname, oname, ename, libs, profile, debug, linker, link = link'} = val proto = Settings.currentProtocol () val lib = if Settings.getBootLinking () then - !Settings.configLib ^ "/" ^ #linkStatic proto ^ " " ^ !Settings.configLib ^ "/liburweb.a " ^ !Settings.configIcuLibs ^ " -licui18n -licuuc -licudata" + !Settings.configLib ^ "/" ^ #linkStatic proto ^ " " ^ !Settings.configLib ^ "/liburweb.a " ^ !Settings.configIcuIncludes ^ " " ^ !Settings.configIcuLibs ^ " -licui18n -licuuc -licudata" else if Settings.getStaticLinking () then - " -static " ^ !Settings.configLib ^ "/" ^ #linkStatic proto ^ " " ^ !Settings.configLib ^ "/liburweb.a " ^ !Settings.configIcuLibs ^ " -licui18n -licuuc -licudata" + " -static " ^ !Settings.configLib ^ "/" ^ #linkStatic proto ^ " " ^ !Settings.configLib ^ "/liburweb.a " ^ !Settings.configIcuIncludes ^ " " ^ !Settings.configIcuLibs ^ " -licui18n -licuuc -licudata" else "-L" ^ !Settings.configLib ^ " " ^ #linkDynamic proto ^ " -lurweb" diff --git a/src/settings.sig b/src/settings.sig index 22dc80a2..29817467 100644 --- a/src/settings.sig +++ b/src/settings.sig @@ -37,6 +37,7 @@ signature SETTINGS = sig val configSrcLib : string ref val configInclude : string ref val configSitelisp : string ref + val configIcuIncludes : string ref val configIcuLibs : string ref val libUr : unit -> string diff --git a/src/settings.sml b/src/settings.sml index 8ae2d377..2e386a4f 100644 --- a/src/settings.sml +++ b/src/settings.sml @@ -32,6 +32,7 @@ val configLib = ref Config.lib val configSrcLib = ref Config.srclib val configInclude = ref Config.includ val configSitelisp = ref Config.sitelisp +val configIcuIncludes = ref Config.icuIncludes val configIcuLibs = ref Config.icuLibs val configCCompiler = ref Config.ccompiler -- cgit v1.2.3 From 05029221a3331f3f0392a4a940a84fb930dfe16d Mon Sep 17 00:00:00 2001 From: fab Date: Mon, 17 Dec 2018 22:59:03 +0000 Subject: test 7 --- src/compiler.sml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/compiler.sml b/src/compiler.sml index 1f77a821..faf5bbe6 100644 --- a/src/compiler.sml +++ b/src/compiler.sml @@ -1585,9 +1585,9 @@ fun compileC {cname, oname, ename, libs, profile, debug, linker, link = link'} = val proto = Settings.currentProtocol () val lib = if Settings.getBootLinking () then - !Settings.configLib ^ "/" ^ #linkStatic proto ^ " " ^ !Settings.configLib ^ "/liburweb.a " ^ !Settings.configIcuIncludes ^ " " ^ !Settings.configIcuLibs ^ " -licui18n -licuuc -licudata" + !Settings.configLib ^ "/" ^ #linkStatic proto ^ " " ^ !Settings.configLib ^ "/liburweb.a " ^ !Settings.configIcuLibs ^ " -licui18n -licuuc -licudata" else if Settings.getStaticLinking () then - " -static " ^ !Settings.configLib ^ "/" ^ #linkStatic proto ^ " " ^ !Settings.configLib ^ "/liburweb.a " ^ !Settings.configIcuIncludes ^ " " ^ !Settings.configIcuLibs ^ " -licui18n -licuuc -licudata" + " -static " ^ !Settings.configLib ^ "/" ^ #linkStatic proto ^ " " ^ !Settings.configLib ^ "/liburweb.a " ^ !Settings.configIcuLibs ^ " -licui18n -licuuc -licudata" else "-L" ^ !Settings.configLib ^ " " ^ #linkDynamic proto ^ " -lurweb" @@ -1598,6 +1598,7 @@ fun compileC {cname, oname, ename, libs, profile, debug, linker, link = link'} = val compile = (Settings.getCCompiler ()) ^ " " ^ Config.ccArgs ^ " " ^ Config.pthreadCflags ^ " -Wimplicit -Werror -Wno-unused-value" ^ opt ^ " -I " ^ !Settings.configInclude + ^ " " ^ !Settings.configIcuIncludes ^ " " ^ #compile proto ^ " -c " ^ escapeFilename cname ^ " -o " ^ escapeFilename oname -- cgit v1.2.3 From 8bb360844cbf9861364fd3f8b39b0f1232711e92 Mon Sep 17 00:00:00 2001 From: fab Date: Mon, 17 Dec 2018 23:16:49 +0000 Subject: getting osx to build on travis. had to change the compiler to insert our icu includes and libs override in cases where the compiler cant find the necessary files in the "normal" places --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1becfb0f..1f768f6d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,10 +1,11 @@ language: c os: - - osx - linux + - osx compiler: + - clang - gcc # when https://github.com/travis-ci/apt-package-whitelist/issues/792 is closed, use the container-based infrastructure @@ -22,7 +23,6 @@ before_install: - if command -v brew &>/dev/null; then brew uninstall libtool; fi - if command -v brew &>/dev/null; then brew install libtool; fi - if command -v brew &>/dev/null; then brew install openssl mlton icu4c; fi - - if command -v brew &>/dev/null; then brew ls --verbose icu4c; fi - if command -v brew &>/dev/null; then export ICU_INCLUDES=-I"`brew --prefix icu4c`/include"; fi - if command -v brew &>/dev/null; then export ICU_LIBS=-L"`brew --prefix icu4c`/lib"; fi - if command -v brew &>/dev/null; then export CONFIGURE_ARGS="--with-openssl=/usr/local/opt/openssl"; fi -- cgit v1.2.3