Browse Source

Fixed utf8.char.

Alex Szpakowski 10 years ago
parent
commit
a17fed2a1e
1 changed files with 27 additions and 1 deletions
  1. 27 1
      src/libraries/luautf8/lutf8lib.c

+ 27 - 1
src/libraries/luautf8/lutf8lib.c

@@ -43,6 +43,9 @@
 
 #define MAXUNICODE	0x10FFFF
 
+/* size of buffer for 'utf8esc' function (taken from lobject.h) */
+#define UTF8BUFFSZ	8
+
 #define iscont(p)	((*(p) & 0xC0) == 0x80)
 
 
@@ -146,10 +149,33 @@ static int codepoint (lua_State *L) {
 }
 
 
+/* taken from lobject.c */
+static int utf8esc (char *buff, unsigned long x) {
+	int n = 1;  /* number of bytes put in buffer (backwards) */
+	lua_assert(x <= 0x10FFFF);
+	if (x < 0x80)  /* ascii? */
+		buff[UTF8BUFFSZ - 1] = (char) x;
+	else {  /* need continuation bytes */
+		unsigned int mfb = 0x3f;  /* maximum that fits in first byte */
+		do {  /* add continuation bytes */
+			buff[UTF8BUFFSZ - (n++)] = (char) (0x80 | (x & 0x3f));
+			x >>= 6;  /* remove added bits */
+			mfb >>= 1;  /* now there is one less bit available in first byte */
+		} while (x > mfb);  /* still needs continuation byte? */
+		buff[UTF8BUFFSZ - n] = (char) ((~mfb << 1) | x);  /* add first byte */
+	}
+	return n;
+}
+
 static void pushutfchar (lua_State *L, int arg) {
   lua_Integer code = luaL_checkinteger(L, arg);
   luaL_argcheck(L, 0 <= code && code <= MAXUNICODE, arg, "value out of range");
-  lua_pushfstring(L, "%U", (long)code);
+
+  /* the %U string format does not exist in lua 5.1 or 5.2, so we emulate it */
+  /* (code from luaO_pushvfstring in lobject.c) */
+  char buff[UTF8BUFFSZ];
+  int l = utf8esc(buff, (long) code);
+  lua_pushlstring(L, buff + UTF8BUFFSZ - l, l);
 }