static int str_format (lua_State *L) { int arg = 1; size_t sfl; const char *strfrmt = luaL_checklstring(L, arg, &sfl); const char *strfrmt_end = strfrmt+sfl; luaL_Buffer b; luaL_buffinit(L, &b); while (strfrmt < strfrmt_end) { if (*strfrmt != L_ESC) luaL_addchar(&b, *strfrmt++); else if (*++strfrmt == L_ESC) luaL_addchar(&b, *strfrmt++); /* %% */ else { /* format item */ char form[MAX_FORMAT]; /* to store the format (`%...') */ char buff[MAX_ITEM]; /* to store the formatted item */ arg++; strfrmt = scanformat(L, strfrmt, form); switch (*strfrmt++) { case 'c': { sprintf(buff, form, (int)luaL_checknumber(L, arg)); break; } case 'd': case 'i': { addintlen(form); sprintf(buff, form, (LUA_INTFRM_T)luaL_checknumber(L, arg)); break; } case 'o': case 'u': case 'x': case 'X': { addintlen(form); sprintf(buff, form, (unsigned LUA_INTFRM_T)luaL_checknumber(L, arg)); break; } case 'e': case 'E': case 'f': case 'g': case 'G': { sprintf(buff, form, (double)luaL_checknumber(L, arg)); break; } case 'q': { addquoted(L, &b, arg); continue; /* skip the 'addsize' at the end */ } case 's': { size_t l; const char *s = luaL_checklstring(L, arg, &l); if (!strchr(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 { sprintf(buff, form, s); break; } } default: { /* also treat cases `pnLlh' */ return luaL_error(L, "invalid option " LUA_QL("%%%c") " to " LUA_QL("format"), *(strfrmt - 1)); } } luaL_addlstring(&b, buff, strlen(buff)); } } 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 != L_ESC) luaL_addwchar(b, *strfrmt++); else if (*++strfrmt == L_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 = scanformat(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': { addintlen(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_addquoted(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; }