this function handles only `%d', `%c', %f, %p, and `%s' formats */
| 120 | |
| 121 | /* this function handles only `%d', `%c', %f, %p, and `%s' formats */ |
| 122 | const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { |
| 123 | int n = 1; |
| 124 | pushstr(L, ""); |
| 125 | for (;;) { |
| 126 | const char *e = strchr(fmt, '%'); |
| 127 | if (e == NULL) break; |
| 128 | setsvalue2s(L, L->top, luaS_newlstr(L, fmt, e-fmt)); |
| 129 | incr_top(L); |
| 130 | switch (*(e+1)) { |
| 131 | case 's': { |
| 132 | const char *s = va_arg(argp, char *); |
| 133 | if (s == NULL) s = "(null)"; |
| 134 | pushstr(L, s); |
| 135 | break; |
| 136 | } |
| 137 | case 'c': { |
| 138 | char buff[2]; |
| 139 | buff[0] = cast(char, va_arg(argp, int)); |
| 140 | buff[1] = '\0'; |
| 141 | pushstr(L, buff); |
| 142 | break; |
| 143 | } |
| 144 | case 'd': { |
| 145 | setnvalue(L->top, cast_num(va_arg(argp, int))); |
| 146 | incr_top(L); |
| 147 | break; |
| 148 | } |
| 149 | case 'f': { |
| 150 | setnvalue(L->top, cast_num(va_arg(argp, l_uacNumber))); |
| 151 | incr_top(L); |
| 152 | break; |
| 153 | } |
| 154 | case 'p': { |
| 155 | char buff[4*sizeof(void *) + 8]; /* should be enough space for a `%p' */ |
| 156 | sprintf(buff, "%p", va_arg(argp, void *)); |
| 157 | pushstr(L, buff); |
| 158 | break; |
| 159 | } |
| 160 | case '%': { |
| 161 | pushstr(L, "%"); |
| 162 | break; |
| 163 | } |
| 164 | default: { |
| 165 | char buff[3]; |
| 166 | buff[0] = '%'; |
| 167 | buff[1] = *(e+1); |
| 168 | buff[2] = '\0'; |
| 169 | pushstr(L, buff); |
| 170 | break; |
| 171 | } |
| 172 | } |
| 173 | n += 2; |
| 174 | fmt = e+2; |
| 175 | } |
| 176 | pushstr(L, fmt); |
| 177 | luaV_concat(L, n+1, cast_int(L->top - L->base) - 1); |
| 178 | L->top -= n; |
| 179 | return svalue(L->top - 1); |
no test coverage detected