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; |
