summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorChris Angelico <rosuav@gmail.com>2014-06-04 05:28:12 +1000
committerPaul Sokolovsky <pfalcon@users.sourceforge.net>2014-06-27 00:04:17 +0300
commitc88987c1af10e19ab2703231d0702202127eb046 (patch)
tree6139a644cfdaed7f2f333fb53bdbe016a11ff71a
parent12bc13eeb82592f768fb0e304bb9b6eaf1c2ce17 (diff)
downloadmicropython-c88987c1af10e19ab2703231d0702202127eb046.tar.gz
micropython-c88987c1af10e19ab2703231d0702202127eb046.zip
py: Implement basic unicode functions.
-rw-r--r--py/misc.h4
-rw-r--r--py/unicode.c33
2 files changed, 32 insertions, 5 deletions
diff --git a/py/misc.h b/py/misc.h
index 3f62e3198f..97e9b30edf 100644
--- a/py/misc.h
+++ b/py/misc.h
@@ -100,7 +100,9 @@ bool unichar_isupper(unichar c);
bool unichar_islower(unichar c);
unichar unichar_tolower(unichar c);
unichar unichar_toupper(unichar c);
-#define unichar_charlen(s, bytelen) (bytelen)
+uint unichar_charlen(const char *str, uint len);
+#define UTF8_IS_NONASCII(ch) ((ch) & 0x80)
+#define UTF8_IS_CONT(ch) (((ch) & 0xC0) == 0x80)
/** variable string *********************************************/
diff --git a/py/unicode.c b/py/unicode.c
index 88f835131d..0da247889e 100644
--- a/py/unicode.c
+++ b/py/unicode.c
@@ -65,14 +65,39 @@ STATIC const uint8_t attr[] = {
AT_LO, AT_LO, AT_LO, AT_PR, AT_PR, AT_PR, AT_PR, 0
};
-unichar utf8_get_char(const byte *s) {
- return *s;
+unichar utf8_get_char(const char *s) {
+ unichar ord = *s++;
+ if (!UTF8_IS_NONASCII(ord)) return ord;
+ ord &= 0x7F;
+ for (unichar mask = 0x40; ord & mask; mask >>= 1) {
+ ord &= ~mask;
+ }
+ while (UTF8_IS_CONT(*s)) {
+ ord = (ord << 6) | (*s++ & 0x3F);
+ }
+ return ord;
+}
+
+char *utf8_next_char(const char *s) {
+ ++s;
+ while (UTF8_IS_CONT(*s)) {
+ ++s;
+ }
+ return (char *)s;
}
-const byte *utf8_next_char(const byte *s) {
- return s + 1;
+uint unichar_charlen(const char *str, uint len)
+{
+ uint charlen = 0;
+ for (const char *top = str + len; str < top; ++str) {
+ if (!UTF8_IS_CONT(*str)) {
+ ++charlen;
+ }
+ }
+ return charlen;
}
+// Be aware: These unichar_is* functions are actually ASCII-only!
bool unichar_isspace(unichar c) {
return c < 128 && (attr[c] & FL_SPACE) != 0;
}