static int uread_chars (lua_State *L, FILE *f, size_t n) { size_t rlen; /* how much to read */ size_t nr; /* number of chars actually read */ luaL_Buffer b; luaL_wbuffinit(L, &b); rlen = LUAL_BUFFERSIZE / 2; /* try to read that much each time */ do { char *p = luaL_prepbuffer(&b); if (rlen > n) rlen = n; /* cannot read more than asked */ nr = fread(p, sizeof(lua_WChar), rlen, f); luaL_addwsize(&b, nr); n -= nr; /* still have to read `n' chars */ } while (n > 0 && nr == rlen); /* until end of count or eof */ luaL_pushresult(&b); /* close buffer */ return (n == 0 || lua_strlen(L, -1) > 0); }
static int uread_line (lua_State *L, FILE *f) { luaL_Buffer b; luaL_wbuffinit(L, &b); for (;;) { size_t l; lua_WChar *p = (lua_WChar*)luaL_prepbuffer(&b); if (fgetws(p, LUAL_BUFFERSIZE / 2, f) == NULL) { /* eof? */ luaL_pushresult(&b); /* close buffer */ return (lua_strlen(L, -1) > 0); /* check whether read something */ } l = lua_WChar_len(p); if (p[l-1] != '\n') luaL_addwsize(&b, l); else { luaL_addwsize(&b, l - 1); /* do not include `eol' */ luaL_pushresult(&b); /* close buffer */ return 1; /* read at least an `eol' */ } } }
static int str_gsub (lua_State *L) { size_t srcl; const lua_WChar *src = luaL_checklwstring(L, 1, &srcl); const lua_WChar *p = luaL_checkwstring(L, 2); int max_s = luaL_optint(L, 4, srcl+1); int anchor = (*p == '^') ? (p++, 1) : 0; int n = 0; MatchState ms; luaL_Buffer b; luaL_argcheck(L, lua_gettop(L) >= 3 && (lua_iswstring(L, 3) || lua_isfunction(L, 3)), 3, "string or function expected"); luaL_wbuffinit(L, &b); ms.L = L; ms.src_init = src; ms.src_end = src+srcl; while (n < max_s) { const lua_WChar *e; ms.level = 0; e = match(&ms, src, p); if (e) { n++; add_s(&ms, &b, src, e); } if (e && e>src) /* non empty match? */ src = e; /* skip it */ else if (src < ms.src_end) luaL_putwchar(&b, *src++); else break; if (anchor) break; } luaL_addlwstring(&b, src, ms.src_end-src); luaL_pushresult(&b); lua_pushnumber(L, n); /* number of substitutions */ return 2; }
static int str_lualex(lua_State *L) { size_t l = 0; const lua_WChar *str = luaL_checklwstring(L, 1, &l); int isWide = luaL_checkint(L, 2) != 0; size_t i; luaL_Buffer b; luaL_wbuffinit(L, &b); for (i = 0; i < l; ++i) { // int needUnicodeZero = 1; switch (str[i]) { case '\\': ++i; switch (str[i]) { case 'a': luaL_putwchar(&b, '\a'); break; case 'b': luaL_putwchar(&b, '\b'); break; case 'f': luaL_putwchar(&b, '\f'); break; case 'n': luaL_putwchar(&b, '\n'); break; case 'r': luaL_putwchar(&b, '\r'); break; case 't': luaL_putwchar(&b, '\t'); break; case 'v': luaL_putwchar(&b, '\v'); break; case 'x': { int ch; ++i; ch = tolower(str[i]); if (!isdigit(ch) && !(ch >= 'a' && ch <= 'f') ) { --i; luaL_putwchar(&b, 'x'); } else { /* \xxx */ int c = 0; int i = 0; int numDigits = isWide ? 4 : 2; do { ch = towlower(str[i]); if (iswdigit((wint_t)ch)) c = 16*c + (ch-'0'); else if (ch >= 'a' && ch <= 'f') c = 16*c + (ch-'a') + 10; ++i; ch = towlower(str[i]); } while (++i<numDigits && iswdigit((wint_t)ch) || (ch >= 'a' && ch <= 'f')); luaL_putwchar(&b, c); // needUnicodeZero = 0; } break; } default: { if (!iswdigit(str[i])) luaL_putwchar(&b, str[i]); else { /* \xxx */ int c = 0; int count = 0; do { c = 10*c + (str[i]-'0'); ++i; } while (++count<3 && iswdigit(str[i])); luaL_putwchar(&b, c); } } } break; default: luaL_putwchar(&b, str[i]); } if (isWide) // && needUnicodeZero) luaL_putwchar(&b, str[i]); } luaL_pushresult(&b); return 1; }
int wstr_format_helper (luaL_Buffer* b, lua_State *L, int arg) { size_t sfl; const lua_WChar *strfrmt = luaL_checklwstring(L, arg, &sfl); const lua_WChar *strfrmt_end = strfrmt+sfl; luaL_wbuffinit(L, b); while (strfrmt < strfrmt_end) { if (*strfrmt != '%') luaL_putwchar(b, *strfrmt++); else if (*++strfrmt == '%') luaL_putwchar(b, *strfrmt++); /* %% */ else { /* format item */ lua_WChar form[MAX_FORMAT]; /* to store the format (`%...') */ lua_WChar buff[MAX_ITEM]; /* to store the formatted item */ int hasprecision = 0; if (iswdigit(*strfrmt) && *(strfrmt+1) == '$') return luaL_error(L, "obsolete `format' option (d$)"); arg++; strfrmt = scanformat(L, strfrmt, form, &hasprecision); switch (*strfrmt++) { case 'b': { buff[1] = buff[2] = buff[3] = buff[4] = buff[5] = buff[6] = buff[7] = buff[8] = 0; switch (*strfrmt++) { case 'b': { unsigned int num = (unsigned int)luaL_checkint(L, arg); buff[0] = (unsigned char)num; luaL_addlwstring(b, buff, 1); break; } case 'd': { unsigned int num = (unsigned int)luaL_checkint(L, arg); *(unsigned int*)(&buff) = num; luaL_addlwstring(b, buff, 4); break; } case 'w': { unsigned int num = (unsigned int)luaL_checkint(L, arg); *(unsigned short*)(&buff) = (unsigned short)num; luaL_addlwstring(b, buff, 2); break; } case 'f': { float numF = (float)luaL_checknumber(L, arg); *(float*)(&buff) = numF; luaL_addlwstring(b, buff, 4); break; } case 'F': { double numD = (double)luaL_checknumber(L, arg); *(double*)(&buff) = numD; luaL_addlwstring(b, buff, 8); break; } default: break; } buff[0] = 0; break; } case 'c': case 'd': case 'i': swprintf(buff, form, luaL_checkint(L, arg)); break; case 'o': case 'u': case 'x': case 'X': //?? How should this be for integers? swprintf(buff, form, (unsigned int)(luaL_checknumber(L, arg))); break; case 'e': case 'E': case 'f': case 'g': case 'G': swprintf(buff, form, luaL_checknumber(L, arg)); break; case 'q': luaI_addquoted(L, b, arg); continue; /* skip the `addsize' at the end */ case 'Q': luaI_addquotedbinary(L, b, arg); continue; /* skip the `addsize' at the end */ case 's': { size_t l; const lua_WChar *s = luaL_checklwstring(L, arg, &l); if (!hasprecision && l >= 100) { /* no precision and string is too long to be formatted; keep original string */ lua_pushvalue(L, arg); luaL_addvalue(b); continue; /* skip the `addsize' at the end */ } else { swprintf(buff, form, s); break; } } default: /* also treat cases `pnLlh' */ luaL_error(L, "invalid option in `format'"); } luaL_addlwstring(b, buff, lua_WChar_len(buff)); } } return 1; }
static int luaB_towstring (lua_State *L) { char buff[64]; switch (lua_type(L, 1)) { case LUA_TNUMBER: lua_pushwstring(L, lua_towstring(L, 1)); return 1; case LUA_TSTRING: { luaL_Buffer b; size_t l; size_t i; const char *s = lua_tostring(L, 1); l = lua_strlen(L, 1); if (l == 0) { lua_pushwstring(L, L""); } else { luaL_wbuffinit(L, &b); for (i=0; i<l; i++) luaL_putwchar(&b, (lua_WChar)s[i]); luaL_pushresult(&b); } return 1; } case LUA_TWSTRING: lua_pushvalue(L, 1); return 1; case LUA_TTABLE: sprintf(buff, "%.40s: %p", lua_type(L, 1), lua_topointer(L, 1)); break; case LUA_TFUNCTION: sprintf(buff, "function: %p", lua_topointer(L, 1)); break; case LUA_TUSERDATA: { const char *t = lua_typename(L, lua_type(L, 1)); if (strcmp(t, "userdata") == 0) sprintf(buff, "userdata: %p", lua_touserdata(L, 1)); else sprintf(buff, "%.40s: %p", t, lua_touserdata(L, 1)); break; } case LUA_TNIL: lua_pushliteral(L, "nil"); return 1; case LUA_TTHREAD: sprintf(buff, "thread: %p", (void *)lua_tothread(L, 1)); break; default: luaL_argerror(L, 1, "value expected"); } { luaL_Buffer b; size_t l; size_t i; const lua_WChar *s = lua_towstring(L, 1); l = lua_strlen(L, 1); luaL_wbuffinit(L, &b); for (i=0; i<l; i++) luaL_putwchar(&b, (lua_WChar)(s[i])); luaL_pushresult(&b); } /* lua_pushstring(L, buff);*/ return 1; }
int wwstr_format_helper (luaL_Buffer* b, lua_State *L, int arg) { size_t sfl; const lua_WChar *strfrmt = luaL_checklwstring(L, arg, &sfl); const lua_WChar *strfrmt_end = strfrmt+sfl; luaL_wbuffinit(L, b); while (strfrmt < strfrmt_end) { if (*strfrmt != WL_ESC) luaL_addwchar(b, *strfrmt++); else if (*++strfrmt == WL_ESC) luaL_addwchar(b, *strfrmt++); /* %% */ else { /* format item */ lua_WChar form[MAX_FORMAT]; /* to store the format (`%...') */ lua_WChar buff[MAX_ITEM]; /* to store the formatted item */ char _form[MAX_FORMAT]; char _buff[MAX_ITEM]; if (iswdigit(*strfrmt) && *(strfrmt+1) == '$') return luaL_error(L, "obsolete `format' option (d$)"); arg++; strfrmt = wscanformat(L, strfrmt, form); switch (*strfrmt++) { case 'c': { translate_wide_to_single(form, _form); sprintf(_buff, _form, luaL_checkint(L, arg)); translate_single_to_wide(_buff, buff); break; } case 'd': case 'i': { waddintlen(form); translate_wide_to_single(form, _form); sprintf(_buff, _form, (LUA_INTFRM_T)luaL_checknumber(L, arg)); translate_single_to_wide(_buff, buff); break; } case 'o': case 'u': case 'x': case 'X': { //?? How should this be for integers? translate_wide_to_single(form, _form); sprintf(_buff, _form, (unsigned LUA_INTFRM_T)luaL_checknumber(L, arg)); translate_single_to_wide(_buff, buff); break; } case 'e': case 'E': case 'f': case 'g': case 'G': { translate_wide_to_single(form, _form); sprintf(_buff, _form, luaL_checknumber(L, arg)); translate_single_to_wide(_buff, buff); break; } case 'q': { luaI_waddquoted(L, b, arg); continue; /* skip the 'addsize' at the end */ } case 's': { size_t l; const lua_WChar *s = luaL_checklwstring(L, arg, &l); (void)s; if (!lua_WChar_chr(form, '.') && l >= 100) { /* no precision and string is too long to be formatted; keep original string */ lua_pushvalue(L, arg); luaL_addvalue(b); continue; /* skip the `addsize' at the end */ } else { assert(0); // swprintf((wchar_t*)buff, (wchar_t*)form, s); break; } } case 'b': { buff[1] = buff[2] = buff[3] = buff[4] = buff[5] = buff[6] = buff[7] = buff[8] = 0; switch (*strfrmt++) { case 'b': { unsigned int num = (unsigned int)luaL_checkint(L, arg); buff[0] = (unsigned char)num; luaL_addlwstring(b, buff, 1); break; } case 'd': { unsigned int num = (unsigned int)luaL_checkint(L, arg); *(unsigned int*)(&buff) = num; luaL_addlwstring(b, buff, 4); break; } case 'w': { unsigned int num = (unsigned int)luaL_checkint(L, arg); *(unsigned short*)(&buff) = (unsigned short)num; luaL_addlwstring(b, buff, 2); break; } case 'f': { float numF = (float)luaL_checknumber(L, arg); *(float*)(&buff) = numF; luaL_addlwstring(b, buff, 4); break; } case 'F': { double numD = (double)luaL_checknumber(L, arg); *(double*)(&buff) = numD; luaL_addlwstring(b, buff, 8); break; } default: break; } buff[0] = 0; break; } } luaL_addlwstring(b, buff, lua_WChar_len(buff)); } } return 1; }