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