diff options
Diffstat (limited to 'lobject.c')
| -rw-r--r-- | lobject.c | 94 |
1 files changed, 76 insertions, 18 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lobject.c,v 1.77 2002/04/22 14:40:23 roberto Exp roberto $ | 2 | ** $Id: lobject.c,v 1.78 2002/05/06 15:51:41 roberto Exp roberto $ |
| 3 | ** Some generic functions over Lua objects | 3 | ** Some generic functions over Lua objects |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -16,6 +16,8 @@ | |||
| 16 | #include "lmem.h" | 16 | #include "lmem.h" |
| 17 | #include "lobject.h" | 17 | #include "lobject.h" |
| 18 | #include "lstate.h" | 18 | #include "lstate.h" |
| 19 | #include "lstring.h" | ||
| 20 | #include "lvm.h" | ||
| 19 | 21 | ||
| 20 | 22 | ||
| 21 | 23 | ||
| @@ -89,17 +91,72 @@ int luaO_str2d (const char *s, lua_Number *result) { | |||
| 89 | } | 91 | } |
| 90 | 92 | ||
| 91 | 93 | ||
| 92 | /* maximum length of a string format for `luaO_verror' */ | ||
| 93 | #define MAX_VERROR 280 | ||
| 94 | 94 | ||
| 95 | /* this function needs to handle only '%d' and '%.XXs' formats */ | 95 | static void pushstr (lua_State *L, const char *str) { |
| 96 | setsvalue(L->top, luaS_new(L, str)); | ||
| 97 | incr_top(L); | ||
| 98 | } | ||
| 99 | |||
| 100 | |||
| 101 | /* this function handles only `%d', `%c', %f, and `%s' formats */ | ||
| 102 | const char *luaO_vpushstr (lua_State *L, const char *fmt, va_list argp) { | ||
| 103 | int n = 0; | ||
| 104 | for (;;) { | ||
| 105 | const char *e = strchr(fmt, '%'); | ||
| 106 | if (e == NULL) break; | ||
| 107 | setsvalue(L->top, luaS_newlstr(L, fmt, e-fmt)); | ||
| 108 | incr_top(L); | ||
| 109 | switch (*(e+1)) { | ||
| 110 | case 's': | ||
| 111 | pushstr(L, va_arg(argp, char *)); | ||
| 112 | break; | ||
| 113 | case 'c': { | ||
| 114 | char buff[2]; | ||
| 115 | buff[0] = va_arg(argp, int); | ||
| 116 | buff[1] = '\0'; | ||
| 117 | pushstr(L, buff); | ||
| 118 | break; | ||
| 119 | } | ||
| 120 | case 'd': | ||
| 121 | setnvalue(L->top, va_arg(argp, int)); | ||
| 122 | incr_top(L); | ||
| 123 | break; | ||
| 124 | case 'f': | ||
| 125 | setnvalue(L->top, va_arg(argp, lua_Number)); | ||
| 126 | incr_top(L); | ||
| 127 | break; | ||
| 128 | case '%': | ||
| 129 | pushstr(L, "%"); | ||
| 130 | break; | ||
| 131 | default: lua_assert(0); | ||
| 132 | } | ||
| 133 | n += 2; | ||
| 134 | fmt = e+2; | ||
| 135 | } | ||
| 136 | pushstr(L, fmt); | ||
| 137 | luaV_strconc(L, n+1, L->top - L->ci->base - 1); | ||
| 138 | L->top -= n; | ||
| 139 | return svalue(L->top - 1); | ||
| 140 | } | ||
| 141 | |||
| 142 | |||
| 143 | const char *luaO_pushstr (lua_State *L, const char *fmt, ...) { | ||
| 144 | const char *msg; | ||
| 145 | va_list argp; | ||
| 146 | va_start(argp, fmt); | ||
| 147 | msg = luaO_vpushstr(L, fmt, argp); | ||
| 148 | va_end(argp); | ||
| 149 | return msg; | ||
| 150 | } | ||
| 151 | |||
| 152 | |||
| 96 | void luaO_verror (lua_State *L, const char *fmt, ...) { | 153 | void luaO_verror (lua_State *L, const char *fmt, ...) { |
| 154 | const char *msg; | ||
| 97 | va_list argp; | 155 | va_list argp; |
| 98 | char buff[MAX_VERROR]; /* to hold formatted message */ | ||
| 99 | va_start(argp, fmt); | 156 | va_start(argp, fmt); |
| 100 | vsprintf(buff, fmt, argp); | 157 | msg = luaO_vpushstr(L, fmt, argp); |
| 101 | va_end(argp); | 158 | va_end(argp); |
| 102 | luaD_runerror(L, buff); | 159 | luaD_runerror(L, msg); |
| 103 | } | 160 | } |
| 104 | 161 | ||
| 105 | 162 | ||
| @@ -108,31 +165,32 @@ void luaO_chunkid (char *out, const char *source, int bufflen) { | |||
| 108 | strncpy(out, source+1, bufflen); /* remove first char */ | 165 | strncpy(out, source+1, bufflen); /* remove first char */ |
| 109 | out[bufflen-1] = '\0'; /* ensures null termination */ | 166 | out[bufflen-1] = '\0'; /* ensures null termination */ |
| 110 | } | 167 | } |
| 111 | else { | 168 | else { /* out = "file `source'", or "file `...source'" */ |
| 112 | if (*source == '@') { | 169 | if (*source == '@') { |
| 113 | int l; | 170 | int l; |
| 114 | source++; /* skip the `@' */ | 171 | source++; /* skip the `@' */ |
| 115 | bufflen -= sizeof("file `...%s'"); | 172 | bufflen -= sizeof(" file `...' "); |
| 116 | l = strlen(source); | 173 | l = strlen(source); |
| 174 | strcpy(out, "file `"); | ||
| 117 | if (l>bufflen) { | 175 | if (l>bufflen) { |
| 118 | source += (l-bufflen); /* get last part of file name */ | 176 | source += (l-bufflen); /* get last part of file name */ |
| 119 | sprintf(out, "file `...%.99s'", source); | 177 | strcat(out, "..."); |
| 120 | } | 178 | } |
| 121 | else | 179 | strcat(out, source); |
| 122 | sprintf(out, "file `%.99s'", source); | 180 | strcat(out, "'"); |
| 123 | } | 181 | } |
| 124 | else { | 182 | else { |
| 125 | int len = strcspn(source, "\n"); /* stop at first newline */ | 183 | int len = strcspn(source, "\n"); /* stop at first newline */ |
| 126 | bufflen -= sizeof("string \"%.*s...\""); | 184 | bufflen -= sizeof(" string \"...\" "); |
| 127 | if (len > bufflen) len = bufflen; | 185 | if (len > bufflen) len = bufflen; |
| 186 | strcpy(out, "string \""); | ||
| 128 | if (source[len] != '\0') { /* must truncate? */ | 187 | if (source[len] != '\0') { /* must truncate? */ |
| 129 | strcpy(out, "string \""); | 188 | strncat(out, source, len); |
| 130 | out += strlen(out); | 189 | strcat(out, "..."); |
| 131 | strncpy(out, source, len); | ||
| 132 | strcpy(out+len, "...\""); | ||
| 133 | } | 190 | } |
| 134 | else | 191 | else |
| 135 | sprintf(out, "string \"%.99s\"", source); | 192 | strcat(out, source); |
| 193 | strcat(out, "\""); | ||
| 136 | } | 194 | } |
| 137 | } | 195 | } |
| 138 | } | 196 | } |
