static void luaI_waddquoted (lua_State *L, luaL_Buffer *b, int arg) { size_t l; const lua_WChar *s = luaL_checklwstring(L, arg, &l); luaL_addwchar(b, '"'); while (l--) { switch (*s) { case '"': case '\\': case '\n': { luaL_addwchar(b, '\\'); luaL_addwchar(b, *s); break; } case '\r': { luaL_addlstring(b, "\\r", 2); break; } case '\0': { luaL_addlwstring(b, (const lua_WChar*)L"\\000", 4); break; } default: { luaL_addwchar(b, *s); break; } } s++; } luaL_addwchar(b, '"'); }
static int wstr_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; WMatchState ms; luaL_Buffer b; 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 = wmatch(&ms, src, p); if (e) { n++; wadd_value(&ms, &b, src, e); } if (e && e>src) /* non empty wmatch? */ src = e; /* skip it */ else if (src < ms.src_end) luaL_addwchar(&b, *src++); else break; if (anchor) break; } luaL_addlwstring(&b, src, ms.src_end-src); luaL_pushresult(&b); lua_pushinteger(L, n); /* number of substitutions */ return 2; }
static int str_rep (lua_State *L) { size_t l; luaL_Buffer b; const lua_WChar *s = luaL_checklwstring(L, 1, &l); int n = luaL_checkint(L, 2); luaL_wbuffinit(L, &b); while (n-- > 0) luaL_addlwstring(&b, s, l); luaL_pushresult(&b); return 1; }
static void luaI_addquoted (lua_State *L, luaL_Buffer *b, int arg) { size_t l; const lua_WChar *s = luaL_checklwstring(L, arg, &l); luaL_putwchar(b, '"'); while (l--) { switch (*s) { case '"': case '\\': case '\n': luaL_putwchar(b, '\\'); luaL_putwchar(b, *s); break; case '\0': luaL_addlwstring(b, L"\\000", 4); break; default: luaL_putwchar(b, *s); } s++; } luaL_putwchar(b, '"'); }
static void wadd_s (WMatchState *ms, luaL_Buffer *b, const lua_WChar *s, const lua_WChar *e) { size_t l, i; const lua_WChar *news = lua_tolwstring(ms->L, 3, &l); for (i = 0; i < l; i++) { if (news[i] != WL_ESC) luaL_addwchar(b, news[i]); else { i++; /* skip ESC */ if (!iswdigit(uchar(news[i]))) luaL_addwchar(b, news[i]); else if (news[i] == '0') luaL_addlwstring(b, s, e - s); else { wpush_onecapture(ms, news[i] - '1', s, e); luaL_addvalue(b); /* add capture to accumulated result */ } } } }
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; }
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; }
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; }
LUALIB_API void luaL_addwstring (luaL_Buffer *B, const lua_WChar *s) { luaL_addlwstring(B, s, lua_WChar_len(s)); }