diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2014-02-06 13:59:24 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2014-02-06 13:59:24 -0200 |
commit | 4ea60463f5a5cc5c30bf3f20be0dd5141f48aa3c (patch) | |
tree | d5330beaf2e11fc249f6c0aaef0b18ab3d9ec22c /lobject.c | |
parent | d438e1379d24f06f027f8fc0e8fc1ff6673b322f (diff) | |
download | lua-4ea60463f5a5cc5c30bf3f20be0dd5141f48aa3c.tar.gz lua-4ea60463f5a5cc5c30bf3f20be0dd5141f48aa3c.tar.bz2 lua-4ea60463f5a5cc5c30bf3f20be0dd5141f48aa3c.zip |
UTF-8 encoding exported as format '%U' in 'lua_pushfstring'
Diffstat (limited to 'lobject.c')
-rw-r--r-- | lobject.c | 28 |
1 files changed, 26 insertions, 2 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lobject.c,v 2.71 2013/12/30 20:47:58 roberto Exp roberto $ | 2 | ** $Id: lobject.c,v 2.72 2014/01/27 13:34:32 roberto Exp roberto $ |
3 | ** Some generic functions over Lua objects | 3 | ** Some generic functions over Lua objects |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -284,12 +284,30 @@ int luaO_str2int (const char *s, size_t len, lua_Integer *result) { | |||
284 | } | 284 | } |
285 | 285 | ||
286 | 286 | ||
287 | int luaO_utf8esc (char *buff, unsigned int x) { | ||
288 | int n = 1; /* number of bytes put in buffer (backwards) */ | ||
289 | if (x < 0x80) /* ascii? */ | ||
290 | buff[UTF8BUFFSZ - 1] = x; | ||
291 | else { /* need continuation bytes */ | ||
292 | unsigned int mfb = 0x3f; /* maximum that fits in first byte */ | ||
293 | do { | ||
294 | buff[UTF8BUFFSZ - (n++)] = 0x80 | (x & 0x3f); /* add continuation byte */ | ||
295 | x >>= 6; /* remove added bits */ | ||
296 | mfb >>= 1; /* now there is one less bit available in first byte */ | ||
297 | } while (x > mfb); /* still needs continuation byte? */ | ||
298 | buff[UTF8BUFFSZ - n] = (~mfb << 1) | x; /* add first byte */ | ||
299 | } | ||
300 | return n; | ||
301 | } | ||
302 | |||
303 | |||
287 | static void pushstr (lua_State *L, const char *str, size_t l) { | 304 | static void pushstr (lua_State *L, const char *str, size_t l) { |
288 | setsvalue2s(L, L->top++, luaS_newlstr(L, str, l)); | 305 | setsvalue2s(L, L->top++, luaS_newlstr(L, str, l)); |
289 | } | 306 | } |
290 | 307 | ||
291 | 308 | ||
292 | /* this function handles only `%d', `%c', %f, %p, and `%s' formats */ | 309 | /* this function handles only '%d', '%c', '%f', '%p', and '%s' |
310 | conventional formats, plus Lua-specific '%L' and '%U' */ | ||
293 | const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { | 311 | const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { |
294 | int n = 0; | 312 | int n = 0; |
295 | for (;;) { | 313 | for (;;) { |
@@ -328,6 +346,12 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { | |||
328 | pushstr(L, buff, l); | 346 | pushstr(L, buff, l); |
329 | break; | 347 | break; |
330 | } | 348 | } |
349 | case 'U': { | ||
350 | char buff[UTF8BUFFSZ]; | ||
351 | int l = luaO_utf8esc(buff, va_arg(argp, int)); | ||
352 | pushstr(L, buff + UTF8BUFFSZ - l, l); | ||
353 | break; | ||
354 | } | ||
331 | case '%': { | 355 | case '%': { |
332 | pushstr(L, "%", 1); | 356 | pushstr(L, "%", 1); |
333 | break; | 357 | break; |