diff options
| -rw-r--r-- | lauxlib.c | 97 | ||||
| -rw-r--r-- | lauxlib.h | 47 | ||||
| -rw-r--r-- | ldo.c | 5 | ||||
| -rw-r--r-- | lgc.c | 8 | ||||
| -rw-r--r-- | liolib.c | 87 | ||||
| -rw-r--r-- | llex.c | 196 | ||||
| -rw-r--r-- | lobject.c | 13 | ||||
| -rw-r--r-- | lobject.h | 3 | ||||
| -rw-r--r-- | lstate.c | 4 | ||||
| -rw-r--r-- | lstate.h | 4 | ||||
| -rw-r--r-- | lstrlib.c | 114 | ||||
| -rw-r--r-- | lundump.c | 4 | ||||
| -rw-r--r-- | lvm.c | 5 |
13 files changed, 376 insertions, 211 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lauxlib.c,v 1.32 2000/08/29 14:33:31 roberto Exp roberto $ | 2 | ** $Id: lauxlib.c,v 1.33 2000/08/29 20:43:28 roberto Exp roberto $ |
| 3 | ** Auxiliary functions for building Lua libraries | 3 | ** Auxiliary functions for building Lua libraries |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -140,8 +140,97 @@ void luaL_chunkid (char *out, const char *source, int len) { | |||
| 140 | } | 140 | } |
| 141 | 141 | ||
| 142 | 142 | ||
| 143 | void luaL_filesource (char *out, const char *filename, int len) { | 143 | /* |
| 144 | if (filename == NULL) filename = "(stdin)"; | 144 | ** {====================================================== |
| 145 | sprintf(out, "@%.*s", len-2, filename); /* -2 for '@' and '\0' */ | 145 | ** Generic Buffer manipulation |
| 146 | ** ======================================================= | ||
| 147 | */ | ||
| 148 | |||
| 149 | |||
| 150 | #define buffempty(B) ((B)->p == (B)->buffer) | ||
| 151 | #define bufflen(B) ((B)->p - (B)->buffer) | ||
| 152 | #define bufffree(B) ((size_t)(LUAL_BUFFERSIZE - bufflen(B))) | ||
| 153 | |||
| 154 | #define LIMIT (LUA_MINSTACK/2) | ||
| 155 | |||
| 156 | |||
| 157 | static int emptybuffer (luaL_Buffer *B) { | ||
| 158 | size_t l = bufflen(B); | ||
| 159 | if (l == 0) return 0; /* put nothing on stack */ | ||
| 160 | else { | ||
| 161 | lua_pushlstring(B->L, B->buffer, l); | ||
| 162 | B->p = B->buffer; | ||
| 163 | B->level++; | ||
| 164 | return 1; | ||
| 165 | } | ||
| 166 | } | ||
| 167 | |||
| 168 | |||
| 169 | static void adjuststack (luaL_Buffer *B) { | ||
| 170 | if (B->level > 1) { | ||
| 171 | lua_State *L = B->L; | ||
| 172 | int toget = 1; /* number of levels to concat */ | ||
| 173 | size_t toplen = lua_strlen(L, -1); | ||
| 174 | do { | ||
| 175 | size_t l = lua_strlen(L, -(toget+1)); | ||
| 176 | if (B->level - toget + 1 >= LIMIT || toplen > l) { | ||
| 177 | toplen += l; | ||
| 178 | toget++; | ||
| 179 | } | ||
| 180 | else break; | ||
| 181 | } while (toget < B->level); | ||
| 182 | if (toget >= 2) { | ||
| 183 | lua_concat(L, toget); | ||
| 184 | B->level = B->level - toget + 1; | ||
| 185 | } | ||
| 186 | } | ||
| 187 | } | ||
| 188 | |||
| 189 | |||
| 190 | char *luaL_prepbuffer (luaL_Buffer *B) { | ||
| 191 | if (emptybuffer(B)) | ||
| 192 | adjuststack(B); | ||
| 193 | return B->buffer; | ||
| 194 | } | ||
| 195 | |||
| 196 | |||
| 197 | void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) { | ||
| 198 | while (l--) | ||
| 199 | luaL_putchar(B, *s++); | ||
| 200 | } | ||
| 201 | |||
| 202 | |||
| 203 | void luaL_pushresult (luaL_Buffer *B) { | ||
| 204 | emptybuffer(B); | ||
| 205 | if (B->level == 0) | ||
| 206 | lua_pushlstring(B->L, NULL, 0); | ||
| 207 | else if (B->level > 1) | ||
| 208 | lua_concat(B->L, B->level); | ||
| 209 | B->level = 1; | ||
| 210 | } | ||
| 211 | |||
| 212 | |||
| 213 | void luaL_addvalue (luaL_Buffer *B) { | ||
| 214 | lua_State *L = B->L; | ||
| 215 | size_t vl = lua_strlen(L, -1); | ||
| 216 | if (vl <= bufffree(B)) { /* fit into buffer? */ | ||
| 217 | memcpy(B->p, lua_tostring(L, -1), vl); /* put it there */ | ||
| 218 | B->p += vl; | ||
| 219 | lua_pop(L, 1); /* remove from stack */ | ||
| 220 | } | ||
| 221 | else { | ||
| 222 | if (emptybuffer(B)) | ||
| 223 | lua_insert(L, -2); /* put buffer before new value */ | ||
| 224 | B->level++; /* add new value into B stack */ | ||
| 225 | adjuststack(B); | ||
| 226 | } | ||
| 227 | } | ||
| 228 | |||
| 229 | |||
| 230 | void luaL_buffinit (lua_State *L, luaL_Buffer *B) { | ||
| 231 | B->L = L; | ||
| 232 | B->p = B->buffer; | ||
| 233 | B->level = 0; | ||
| 146 | } | 234 | } |
| 147 | 235 | ||
| 236 | /* }====================================================== */ | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lauxlib.h,v 1.21 2000/08/29 20:43:28 roberto Exp roberto $ | 2 | ** $Id: lauxlib.h,v 1.22 2000/09/04 18:27:32 roberto Exp roberto $ |
| 3 | ** Auxiliary functions for building Lua libraries | 3 | ** Auxiliary functions for building Lua libraries |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -10,6 +10,7 @@ | |||
| 10 | 10 | ||
| 11 | 11 | ||
| 12 | #include <stddef.h> | 12 | #include <stddef.h> |
| 13 | #include <stdio.h> | ||
| 13 | 14 | ||
| 14 | #include "lua.h" | 15 | #include "lua.h" |
| 15 | 16 | ||
| @@ -34,18 +35,8 @@ void luaL_checktype (lua_State *L, int narg, const char *tname); | |||
| 34 | void luaL_verror (lua_State *L, const char *fmt, ...); | 35 | void luaL_verror (lua_State *L, const char *fmt, ...); |
| 35 | int luaL_findstring (const char *name, const char *const list[]); | 36 | int luaL_findstring (const char *name, const char *const list[]); |
| 36 | void luaL_chunkid (char *out, const char *source, int len); | 37 | void luaL_chunkid (char *out, const char *source, int len); |
| 37 | void luaL_filesource (char *out, const char *filename, int len); | ||
| 38 | 38 | ||
| 39 | 39 | ||
| 40 | char *luaL_openspace (lua_State *L, size_t size); | ||
| 41 | void luaL_resetbuffer (lua_State *L); | ||
| 42 | void luaL_addchar (lua_State *L, int c); | ||
| 43 | size_t luaL_getsize (lua_State *L); | ||
| 44 | void luaL_addsize (lua_State *L, size_t n); | ||
| 45 | size_t luaL_newbuffer (lua_State *L, size_t size); | ||
| 46 | void luaL_oldbuffer (lua_State *L, size_t old); | ||
| 47 | char *luaL_buffer (lua_State *L); | ||
| 48 | |||
| 49 | 40 | ||
| 50 | /* | 41 | /* |
| 51 | ** =============================================================== | 42 | ** =============================================================== |
| @@ -64,5 +55,39 @@ char *luaL_buffer (lua_State *L); | |||
| 64 | #define luaL_openl(L,a) luaL_openlib(L, a, (sizeof(a)/sizeof(a[0]))) | 55 | #define luaL_openl(L,a) luaL_openlib(L, a, (sizeof(a)/sizeof(a[0]))) |
| 65 | 56 | ||
| 66 | 57 | ||
| 58 | /* | ||
| 59 | ** {====================================================== | ||
| 60 | ** Generic Buffer manipulation | ||
| 61 | ** ======================================================= | ||
| 62 | */ | ||
| 63 | |||
| 64 | |||
| 65 | #define LUAL_BUFFERSIZE BUFSIZ | ||
| 66 | |||
| 67 | |||
| 68 | typedef struct luaL_Buffer { | ||
| 69 | char *p; /* current position in buffer */ | ||
| 70 | int level; | ||
| 71 | lua_State *L; | ||
| 72 | char buffer[LUAL_BUFFERSIZE]; | ||
| 73 | } luaL_Buffer; | ||
| 74 | |||
| 75 | #define luaL_putchar(B,c) \ | ||
| 76 | ((void)((B)->p < &(B)->buffer[LUAL_BUFFERSIZE] || luaL_prepbuffer(B)), \ | ||
| 77 | (*(B)->p++ = (char)(c))) | ||
| 78 | |||
| 79 | #define luaL_addsize(B,n) ((B)->p += (n)) | ||
| 80 | |||
| 81 | void luaL_buffinit (lua_State *L, luaL_Buffer *B); | ||
| 82 | char *luaL_prepbuffer (luaL_Buffer *B); | ||
| 83 | void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l); | ||
| 84 | void luaL_addvalue (luaL_Buffer *B); | ||
| 85 | void luaL_pushresult (luaL_Buffer *B); | ||
| 86 | |||
| 87 | |||
| 88 | /* }====================================================== */ | ||
| 89 | |||
| 90 | |||
| 67 | #endif | 91 | #endif |
| 68 | 92 | ||
| 93 | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldo.c,v 1.92 2000/08/31 13:31:44 roberto Exp roberto $ | 2 | ** $Id: ldo.c,v 1.93 2000/09/04 18:52:51 roberto Exp roberto $ |
| 3 | ** Stack and Call structure of Lua | 3 | ** Stack and Call structure of Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -293,7 +293,8 @@ static int parse_file (lua_State *L, const char *filename) { | |||
| 293 | int c; /* look ahead char */ | 293 | int c; /* look ahead char */ |
| 294 | FILE *f = (filename == NULL) ? stdin : fopen(filename, "r"); | 294 | FILE *f = (filename == NULL) ? stdin : fopen(filename, "r"); |
| 295 | if (f == NULL) return LUA_ERRFILE; /* unable to open file */ | 295 | if (f == NULL) return LUA_ERRFILE; /* unable to open file */ |
| 296 | luaL_filesource(source, filename, sizeof(source)); | 296 | if (filename == NULL) filename = "(stdin)"; |
| 297 | sprintf(source, "@%.*s", (int)sizeof(source)-2, filename); | ||
| 297 | c = fgetc(f); | 298 | c = fgetc(f); |
| 298 | ungetc(c, f); | 299 | ungetc(c, f); |
| 299 | bin = (c == ID_CHUNK); | 300 | bin = (c == ID_CHUNK); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lgc.c,v 1.63 2000/08/22 17:44:17 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 1.64 2000/08/28 17:57:04 roberto Exp roberto $ |
| 3 | ** Garbage Collector | 3 | ** Garbage Collector |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -333,6 +333,8 @@ void luaC_collect (lua_State *L, int all) { | |||
| 333 | } | 333 | } |
| 334 | 334 | ||
| 335 | 335 | ||
| 336 | #define MINBUFFER 256 | ||
| 337 | |||
| 336 | long lua_collectgarbage (lua_State *L, long limit) { | 338 | long lua_collectgarbage (lua_State *L, long limit) { |
| 337 | unsigned long recovered = L->nblocks; /* to subtract `nblocks' after gc */ | 339 | unsigned long recovered = L->nblocks; /* to subtract `nblocks' after gc */ |
| 338 | markall(L); | 340 | markall(L); |
| @@ -340,8 +342,8 @@ long lua_collectgarbage (lua_State *L, long limit) { | |||
| 340 | luaC_collect(L, 0); | 342 | luaC_collect(L, 0); |
| 341 | recovered = recovered - L->nblocks; | 343 | recovered = recovered - L->nblocks; |
| 342 | L->GCthreshold = (limit == 0) ? 2*L->nblocks : L->nblocks+limit; | 344 | L->GCthreshold = (limit == 0) ? 2*L->nblocks : L->nblocks+limit; |
| 343 | if (L->Mbuffsize > L->Mbuffnext*4) { /* is buffer too big? */ | 345 | if (L->Mbuffsize > MINBUFFER*2) { /* is buffer too big? */ |
| 344 | L->Mbuffsize /= 2; /* still larger than Mbuffnext*2 */ | 346 | L->Mbuffsize /= 2; /* still larger than MINBUFFER */ |
| 345 | luaM_reallocvector(L, L->Mbuffer, L->Mbuffsize, char); | 347 | luaM_reallocvector(L, L->Mbuffer, L->Mbuffsize, char); |
| 346 | } | 348 | } |
| 347 | callgcTM(L, &luaO_nilobject); | 349 | callgcTM(L, &luaO_nilobject); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: liolib.c,v 1.76 2000/08/31 20:23:40 roberto Exp roberto $ | 2 | ** $Id: liolib.c,v 1.77 2000/09/05 19:33:32 roberto Exp $ |
| 3 | ** Standard I/O (and system) library | 3 | ** Standard I/O (and system) library |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -263,7 +263,7 @@ static int read_pattern (lua_State *L, FILE *f, const char *p) { | |||
| 263 | if (c == NEED_OTHER) c = getc(f); | 263 | if (c == NEED_OTHER) c = getc(f); |
| 264 | m = (c==EOF) ? 0 : luaI_singlematch(c, p, ep); | 264 | m = (c==EOF) ? 0 : luaI_singlematch(c, p, ep); |
| 265 | if (m) { | 265 | if (m) { |
| 266 | if (!inskip) luaL_addchar(L, c); | 266 | if (!inskip) luaL_putchar(L, c); |
| 267 | c = NEED_OTHER; | 267 | c = NEED_OTHER; |
| 268 | } | 268 | } |
| 269 | switch (*ep) { | 269 | switch (*ep) { |
| @@ -274,7 +274,7 @@ static int read_pattern (lua_State *L, FILE *f, const char *p) { | |||
| 274 | while (m) { /* reads the same item until it fails */ | 274 | while (m) { /* reads the same item until it fails */ |
| 275 | c = getc(f); | 275 | c = getc(f); |
| 276 | m = (c==EOF) ? 0 : luaI_singlematch(c, p, ep); | 276 | m = (c==EOF) ? 0 : luaI_singlematch(c, p, ep); |
| 277 | if (m && !inskip) luaL_addchar(L, c); | 277 | if (m && !inskip) luaL_putchar(L, c); |
| 278 | } | 278 | } |
| 279 | /* go through to continue reading the pattern */ | 279 | /* go through to continue reading the pattern */ |
| 280 | case '?': /* optional */ | 280 | case '?': /* optional */ |
| @@ -308,53 +308,74 @@ static int read_number (lua_State *L, FILE *f) { | |||
| 308 | } | 308 | } |
| 309 | 309 | ||
| 310 | 310 | ||
| 311 | static void read_word (lua_State *L, FILE *f) { | 311 | static int read_word (lua_State *L, FILE *f) { |
| 312 | int c; | 312 | int c; |
| 313 | luaL_Buffer b; | ||
| 314 | luaL_buffinit(L, &b); | ||
| 313 | do { c = fgetc(f); } while (isspace(c)); /* skip spaces */ | 315 | do { c = fgetc(f); } while (isspace(c)); /* skip spaces */ |
| 314 | while (c != EOF && !isspace(c)) { | 316 | while (c != EOF && !isspace(c)) { |
| 315 | luaL_addchar(L, c); | 317 | luaL_putchar(&b, c); |
| 316 | c = fgetc(f); | 318 | c = fgetc(f); |
| 317 | } | 319 | } |
| 318 | ungetc(c, f); | 320 | ungetc(c, f); |
| 321 | luaL_pushresult(&b); /* close buffer */ | ||
| 322 | return (lua_strlen(L, 1) > 0); | ||
| 319 | } | 323 | } |
| 320 | 324 | ||
| 321 | 325 | ||
| 322 | #define HUNK_LINE 256 | ||
| 323 | #define HUNK_FILE BUFSIZ | ||
| 324 | |||
| 325 | static int read_line (lua_State *L, FILE *f) { | 326 | static int read_line (lua_State *L, FILE *f) { |
| 326 | int n; | 327 | int n = 0; |
| 327 | char *b; | 328 | luaL_Buffer b; |
| 329 | luaL_buffinit(L, &b); | ||
| 328 | for (;;) { | 330 | for (;;) { |
| 329 | b = luaL_openspace(L, HUNK_LINE); | 331 | char *p = luaL_prepbuffer(&b); |
| 330 | if (!fgets(b, HUNK_LINE, f)) return 0; /* read fails */ | 332 | if (!fgets(p, LUAL_BUFFERSIZE, f)) /* read fails? */ |
| 331 | n = strlen(b); | 333 | break; |
| 332 | if (b[n-1] != '\n') | 334 | n = strlen(p); |
| 333 | luaL_addsize(L, n); | 335 | if (p[n-1] != '\n') |
| 336 | luaL_addsize(&b, n); | ||
| 334 | else { | 337 | else { |
| 335 | luaL_addsize(L, n-1); /* do not add the `\n' */ | 338 | luaL_addsize(&b, n-1); /* do not add the `\n' */ |
| 336 | break; | 339 | break; |
| 337 | } | 340 | } |
| 338 | } | 341 | } |
| 339 | return 1; | 342 | luaL_pushresult(&b); /* close buffer */ |
| 343 | return (n > 0); /* read something? */ | ||
| 340 | } | 344 | } |
| 341 | 345 | ||
| 342 | 346 | ||
| 343 | static void read_file (lua_State *L, FILE *f) { | 347 | static void read_file (lua_State *L, FILE *f) { |
| 344 | size_t n; | 348 | size_t len = 0; |
| 345 | do { | 349 | size_t size = BUFSIZ; |
| 346 | char *b = luaL_openspace(L, HUNK_FILE); | 350 | char *buffer = NULL; |
| 347 | n = fread(b, sizeof(char), HUNK_FILE, f); | 351 | for (;;) { |
| 348 | luaL_addsize(L, n); | 352 | buffer = (char *)realloc(buffer, size); |
| 349 | } while (n==HUNK_FILE); | 353 | if (buffer == NULL) |
| 354 | lua_error(L, "not enough memory to read a file"); | ||
| 355 | len += fread(buffer+len, sizeof(char), size-len, f); | ||
| 356 | if (len < size) break; /* did not read all it could */ | ||
| 357 | size *= 2; | ||
| 358 | } | ||
| 359 | lua_pushlstring(L, buffer, len); | ||
| 360 | free(buffer); | ||
| 350 | } | 361 | } |
| 351 | 362 | ||
| 352 | 363 | ||
| 353 | static int read_chars (lua_State *L, FILE *f, size_t n) { | 364 | static int read_chars (lua_State *L, FILE *f, size_t n) { |
| 354 | char *b = luaL_openspace(L, n); | 365 | char *buffer; |
| 355 | size_t n1 = fread(b, sizeof(char), n, f); | 366 | size_t n1; |
| 356 | luaL_addsize(L, n1); | 367 | char statbuff[BUFSIZ]; |
| 357 | return (n == n1); | 368 | if (n <= BUFSIZ) |
| 369 | buffer = statbuff; | ||
| 370 | else { | ||
| 371 | buffer = (char *)malloc(n); | ||
| 372 | if (buffer == NULL) | ||
| 373 | lua_error(L, "not enough memory to read a file"); | ||
| 374 | } | ||
| 375 | n1 = fread(buffer, sizeof(char), n, f); | ||
| 376 | lua_pushlstring(L, buffer, n1); | ||
| 377 | if (buffer != statbuff) free(buffer); | ||
| 378 | return (n1 > 0 || n == 0); | ||
| 358 | } | 379 | } |
| 359 | 380 | ||
| 360 | 381 | ||
| @@ -375,9 +396,7 @@ static int io_read (lua_State *L) { | |||
| 375 | else | 396 | else |
| 376 | luaL_checkstack(L, lastarg-firstarg+1, "too many arguments"); | 397 | luaL_checkstack(L, lastarg-firstarg+1, "too many arguments"); |
| 377 | for (n = firstarg; n<=lastarg; n++) { | 398 | for (n = firstarg; n<=lastarg; n++) { |
| 378 | size_t l; | ||
| 379 | int success; | 399 | int success; |
| 380 | luaL_resetbuffer(L); | ||
| 381 | if (lua_isnumber(L, n)) | 400 | if (lua_isnumber(L, n)) |
| 382 | success = read_chars(L, f, (size_t)lua_tonumber(L, n)); | 401 | success = read_chars(L, f, (size_t)lua_tonumber(L, n)); |
| 383 | else { | 402 | else { |
| @@ -397,8 +416,7 @@ static int io_read (lua_State *L) { | |||
| 397 | success = 1; /* always success */ | 416 | success = 1; /* always success */ |
| 398 | break; | 417 | break; |
| 399 | case 'w': /* word */ | 418 | case 'w': /* word */ |
| 400 | read_word(L, f); | 419 | success = read_word(L, f); |
| 401 | success = 0; /* must read something to succeed */ | ||
| 402 | break; | 420 | break; |
| 403 | default: | 421 | default: |
| 404 | luaL_argerror(L, n, "invalid format"); | 422 | luaL_argerror(L, n, "invalid format"); |
| @@ -406,9 +424,10 @@ static int io_read (lua_State *L) { | |||
| 406 | } | 424 | } |
| 407 | } | 425 | } |
| 408 | } | 426 | } |
| 409 | l = luaL_getsize(L); | 427 | if (!success) { |
| 410 | if (!success && l==0) break; /* read fails */ | 428 | lua_pop(L, 1); /* remove last result */ |
| 411 | lua_pushlstring(L, luaL_buffer(L), l); | 429 | break; /* read fails */ |
| 430 | } | ||
| 412 | } endloop: | 431 | } endloop: |
| 413 | return n - firstarg; | 432 | return n - firstarg; |
| 414 | } | 433 | } |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: llex.c,v 1.67 2000/08/09 19:16:57 roberto Exp roberto $ | 2 | ** $Id: llex.c,v 1.68 2000/08/22 20:07:56 roberto Exp $ |
| 3 | ** Lexical Analyzer | 3 | ** Lexical Analyzer |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -27,9 +27,6 @@ | |||
| 27 | #define next(LS) (LS->current = zgetc(LS->z)) | 27 | #define next(LS) (LS->current = zgetc(LS->z)) |
| 28 | 28 | ||
| 29 | 29 | ||
| 30 | #define save(L, c) luaL_addchar(L, c) | ||
| 31 | #define save_and_next(L, LS) (save(L, LS->current), next(LS)) | ||
| 32 | |||
| 33 | 30 | ||
| 34 | /* ORDER RESERVED */ | 31 | /* ORDER RESERVED */ |
| 35 | static const char *const token2string [] = { | 32 | static const char *const token2string [] = { |
| @@ -70,10 +67,8 @@ void luaX_syntaxerror (LexState *ls, const char *s, const char *token) { | |||
| 70 | void luaX_error (LexState *ls, const char *s, int token) { | 67 | void luaX_error (LexState *ls, const char *s, int token) { |
| 71 | char buff[TOKEN_LEN]; | 68 | char buff[TOKEN_LEN]; |
| 72 | luaX_token2str(token, buff); | 69 | luaX_token2str(token, buff); |
| 73 | if (buff[0] == '\0') { | 70 | if (buff[0] == '\0') |
| 74 | save(ls->L, '\0'); | 71 | luaX_syntaxerror(ls, s, ls->L->Mbuffer); |
| 75 | luaX_syntaxerror(ls, s, luaL_buffer(ls->L)); | ||
| 76 | } | ||
| 77 | else | 72 | else |
| 78 | luaX_syntaxerror(ls, s, buff); | 73 | luaX_syntaxerror(ls, s, buff); |
| 79 | } | 74 | } |
| @@ -96,16 +91,6 @@ static void luaX_invalidchar (LexState *ls, int c) { | |||
| 96 | } | 91 | } |
| 97 | 92 | ||
| 98 | 93 | ||
| 99 | static const char *readname (lua_State *L, LexState *LS) { | ||
| 100 | luaL_resetbuffer(L); | ||
| 101 | do { | ||
| 102 | save_and_next(L, LS); | ||
| 103 | } while (isalnum(LS->current) || LS->current == '_'); | ||
| 104 | save(L, '\0'); | ||
| 105 | return L->Mbuffer+L->Mbuffbase; | ||
| 106 | } | ||
| 107 | |||
| 108 | |||
| 109 | static void inclinenumber (LexState *LS) { | 94 | static void inclinenumber (LexState *LS) { |
| 110 | next(LS); /* skip '\n' */ | 95 | next(LS); /* skip '\n' */ |
| 111 | ++LS->linenumber; | 96 | ++LS->linenumber; |
| @@ -138,61 +123,133 @@ void luaX_setinput (lua_State *L, LexState *LS, ZIO *z, TString *source) { | |||
| 138 | */ | 123 | */ |
| 139 | 124 | ||
| 140 | 125 | ||
| 126 | /* use Mbuffer to store names, literal strings and numbers */ | ||
| 127 | |||
| 128 | #define EXTRABUFF 128 | ||
| 129 | #define checkbuffer(L, n, len) if ((len)+(n) > L->Mbuffsize) \ | ||
| 130 | luaO_openspace(L, (len)+(n)+EXTRABUFF) | ||
| 131 | |||
| 132 | #define save(L, c, l) (L->Mbuffer[l++] = (char)c) | ||
| 133 | #define save_and_next(L, LS, l) (save(L, LS->current, l), next(LS)) | ||
| 134 | |||
| 141 | 135 | ||
| 142 | static void read_long_string (lua_State *L, LexState *LS) { | 136 | static const char *readname (LexState *LS) { |
| 137 | lua_State *L = LS->L; | ||
| 138 | size_t l = 0; | ||
| 139 | checkbuffer(L, 10, l); | ||
| 140 | do { | ||
| 141 | checkbuffer(L, 10, l); | ||
| 142 | save_and_next(L, LS, l); | ||
| 143 | } while (isalnum(LS->current) || LS->current == '_'); | ||
| 144 | save(L, '\0', l); | ||
| 145 | return L->Mbuffer; | ||
| 146 | } | ||
| 147 | |||
| 148 | |||
| 149 | /* LUA_NUMBER */ | ||
| 150 | static void read_number (LexState *LS, int comma) { | ||
| 151 | lua_State *L = LS->L; | ||
| 152 | size_t l = 0; | ||
| 153 | checkbuffer(L, 10, l); | ||
| 154 | if (comma) save(L, '.', l); | ||
| 155 | while (isdigit(LS->current)) { | ||
| 156 | checkbuffer(L, 10, l); | ||
| 157 | save_and_next(L, LS, l); | ||
| 158 | } | ||
| 159 | if (LS->current == '.') { | ||
| 160 | save_and_next(L, LS, l); | ||
| 161 | if (LS->current == '.') { | ||
| 162 | save_and_next(L, LS, l); | ||
| 163 | save(L, '\0', l); | ||
| 164 | luaX_error(LS, "ambiguous syntax" | ||
| 165 | " (decimal point x string concatenation)", TK_NUMBER); | ||
| 166 | } | ||
| 167 | } | ||
| 168 | while (isdigit(LS->current)) { | ||
| 169 | checkbuffer(L, 10, l); | ||
| 170 | save_and_next(L, LS, l); | ||
| 171 | } | ||
| 172 | if (LS->current == 'e' || LS->current == 'E') { | ||
| 173 | save_and_next(L, LS, l); /* read 'E' */ | ||
| 174 | if (LS->current == '+' || LS->current == '-') | ||
| 175 | save_and_next(L, LS, l); /* optional exponent sign */ | ||
| 176 | while (isdigit(LS->current)) { | ||
| 177 | checkbuffer(L, 10, l); | ||
| 178 | save_and_next(L, LS, l); | ||
| 179 | } | ||
| 180 | } | ||
| 181 | save(L, '\0', l); | ||
| 182 | if (!luaO_str2d(L->Mbuffer, &LS->t.seminfo.r)) | ||
| 183 | luaX_error(LS, "malformed number", TK_NUMBER); | ||
| 184 | } | ||
| 185 | |||
| 186 | |||
| 187 | static void read_long_string (LexState *LS) { | ||
| 188 | lua_State *L = LS->L; | ||
| 143 | int cont = 0; | 189 | int cont = 0; |
| 190 | size_t l = 0; | ||
| 191 | checkbuffer(L, 10, l); | ||
| 192 | save(L, '[', l); /* save first '[' */ | ||
| 193 | save_and_next(L, LS, l); /* pass the second '[' */ | ||
| 144 | for (;;) { | 194 | for (;;) { |
| 195 | checkbuffer(L, 10, l); | ||
| 145 | switch (LS->current) { | 196 | switch (LS->current) { |
| 146 | case EOZ: | 197 | case EOZ: |
| 198 | save(L, '\0', l); | ||
| 147 | luaX_error(LS, "unfinished long string", TK_STRING); | 199 | luaX_error(LS, "unfinished long string", TK_STRING); |
| 148 | break; /* to avoid warnings */ | 200 | break; /* to avoid warnings */ |
| 149 | case '[': | 201 | case '[': |
| 150 | save_and_next(L, LS); | 202 | save_and_next(L, LS, l); |
| 151 | if (LS->current == '[') { | 203 | if (LS->current == '[') { |
| 152 | cont++; | 204 | cont++; |
| 153 | save_and_next(L, LS); | 205 | save_and_next(L, LS, l); |
| 154 | } | 206 | } |
| 155 | continue; | 207 | continue; |
| 156 | case ']': | 208 | case ']': |
| 157 | save_and_next(L, LS); | 209 | save_and_next(L, LS, l); |
| 158 | if (LS->current == ']') { | 210 | if (LS->current == ']') { |
| 159 | if (cont == 0) goto endloop; | 211 | if (cont == 0) goto endloop; |
| 160 | cont--; | 212 | cont--; |
| 161 | save_and_next(L, LS); | 213 | save_and_next(L, LS, l); |
| 162 | } | 214 | } |
| 163 | continue; | 215 | continue; |
| 164 | case '\n': | 216 | case '\n': |
| 165 | save(L, '\n'); | 217 | save(L, '\n', l); |
| 166 | inclinenumber(LS); | 218 | inclinenumber(LS); |
| 167 | continue; | 219 | continue; |
| 168 | default: | 220 | default: |
| 169 | save_and_next(L, LS); | 221 | save_and_next(L, LS, l); |
| 170 | } | 222 | } |
| 171 | } endloop: | 223 | } endloop: |
| 172 | save_and_next(L, LS); /* skip the second ']' */ | 224 | save_and_next(L, LS, l); /* skip the second ']' */ |
| 173 | LS->t.seminfo.ts = luaS_newlstr(L, L->Mbuffer+(L->Mbuffbase+2), | 225 | save(L, '\0', l); |
| 174 | L->Mbuffnext-L->Mbuffbase-4); | 226 | LS->t.seminfo.ts = luaS_newlstr(L, L->Mbuffer+2, l-5); |
| 175 | } | 227 | } |
| 176 | 228 | ||
| 177 | 229 | ||
| 178 | static void read_string (lua_State *L, LexState *LS, int del) { | 230 | static void read_string (LexState *LS, int del) { |
| 179 | save_and_next(L, LS); | 231 | lua_State *L = LS->L; |
| 232 | size_t l = 0; | ||
| 233 | checkbuffer(L, 10, l); | ||
| 234 | save_and_next(L, LS, l); | ||
| 180 | while (LS->current != del) { | 235 | while (LS->current != del) { |
| 236 | checkbuffer(L, 10, l); | ||
| 181 | switch (LS->current) { | 237 | switch (LS->current) { |
| 182 | case EOZ: case '\n': | 238 | case EOZ: case '\n': |
| 239 | save(L, '\0', l); | ||
| 183 | luaX_error(LS, "unfinished string", TK_STRING); | 240 | luaX_error(LS, "unfinished string", TK_STRING); |
| 184 | break; /* to avoid warnings */ | 241 | break; /* to avoid warnings */ |
| 185 | case '\\': | 242 | case '\\': |
| 186 | next(LS); /* do not save the '\' */ | 243 | next(LS); /* do not save the '\' */ |
| 187 | switch (LS->current) { | 244 | switch (LS->current) { |
| 188 | case 'a': save(L, '\a'); next(LS); break; | 245 | case 'a': save(L, '\a', l); next(LS); break; |
| 189 | case 'b': save(L, '\b'); next(LS); break; | 246 | case 'b': save(L, '\b', l); next(LS); break; |
| 190 | case 'f': save(L, '\f'); next(LS); break; | 247 | case 'f': save(L, '\f', l); next(LS); break; |
| 191 | case 'n': save(L, '\n'); next(LS); break; | 248 | case 'n': save(L, '\n', l); next(LS); break; |
| 192 | case 'r': save(L, '\r'); next(LS); break; | 249 | case 'r': save(L, '\r', l); next(LS); break; |
| 193 | case 't': save(L, '\t'); next(LS); break; | 250 | case 't': save(L, '\t', l); next(LS); break; |
| 194 | case 'v': save(L, '\v'); next(LS); break; | 251 | case 'v': save(L, '\v', l); next(LS); break; |
| 195 | case '\n': save(L, '\n'); inclinenumber(LS); break; | 252 | case '\n': save(L, '\n', l); inclinenumber(LS); break; |
| 196 | case '0': case '1': case '2': case '3': case '4': | 253 | case '0': case '1': case '2': case '3': case '4': |
| 197 | case '5': case '6': case '7': case '8': case '9': { | 254 | case '5': case '6': case '7': case '8': case '9': { |
| 198 | int c = 0; | 255 | int c = 0; |
| @@ -201,28 +258,28 @@ static void read_string (lua_State *L, LexState *LS, int del) { | |||
| 201 | c = 10*c + (LS->current-'0'); | 258 | c = 10*c + (LS->current-'0'); |
| 202 | next(LS); | 259 | next(LS); |
| 203 | } while (++i<3 && isdigit(LS->current)); | 260 | } while (++i<3 && isdigit(LS->current)); |
| 204 | if (c != (unsigned char)c) | 261 | if (c != (unsigned char)c) { |
| 262 | save(L, '\0', l); | ||
| 205 | luaX_error(LS, "escape sequence too large", TK_STRING); | 263 | luaX_error(LS, "escape sequence too large", TK_STRING); |
| 206 | save(L, c); | 264 | } |
| 265 | save(L, c, l); | ||
| 207 | break; | 266 | break; |
| 208 | } | 267 | } |
| 209 | default: /* handles \\, \", \', and \? */ | 268 | default: /* handles \\, \", \', and \? */ |
| 210 | save(L, LS->current); | 269 | save_and_next(L, LS, l); |
| 211 | next(LS); | ||
| 212 | } | 270 | } |
| 213 | break; | 271 | break; |
| 214 | default: | 272 | default: |
| 215 | save_and_next(L, LS); | 273 | save_and_next(L, LS, l); |
| 216 | } | 274 | } |
| 217 | } | 275 | } |
| 218 | save_and_next(L, LS); /* skip delimiter */ | 276 | save_and_next(L, LS, l); /* skip delimiter */ |
| 219 | LS->t.seminfo.ts = luaS_newlstr(L, L->Mbuffer+(L->Mbuffbase+1), | 277 | save(L, '\0', l); |
| 220 | L->Mbuffnext-L->Mbuffbase-2); | 278 | LS->t.seminfo.ts = luaS_newlstr(L, L->Mbuffer+1, l-3); |
| 221 | } | 279 | } |
| 222 | 280 | ||
| 223 | 281 | ||
| 224 | int luaX_lex (LexState *LS) { | 282 | int luaX_lex (LexState *LS) { |
| 225 | lua_State *L = LS->L; | ||
| 226 | for (;;) { | 283 | for (;;) { |
| 227 | switch (LS->current) { | 284 | switch (LS->current) { |
| 228 | 285 | ||
| @@ -245,12 +302,10 @@ int luaX_lex (LexState *LS) { | |||
| 245 | continue; | 302 | continue; |
| 246 | 303 | ||
| 247 | case '[': | 304 | case '[': |
| 248 | luaL_resetbuffer(L); | 305 | next(LS); |
| 249 | save_and_next(L, LS); | ||
| 250 | if (LS->current != '[') return '['; | 306 | if (LS->current != '[') return '['; |
| 251 | else { | 307 | else { |
| 252 | save_and_next(L, LS); /* pass the second '[' */ | 308 | read_long_string(LS); |
| 253 | read_long_string(L, LS); | ||
| 254 | return TK_STRING; | 309 | return TK_STRING; |
| 255 | } | 310 | } |
| 256 | 311 | ||
| @@ -276,13 +331,11 @@ int luaX_lex (LexState *LS) { | |||
| 276 | 331 | ||
| 277 | case '"': | 332 | case '"': |
| 278 | case '\'': | 333 | case '\'': |
| 279 | luaL_resetbuffer(L); | 334 | read_string(LS, LS->current); |
| 280 | read_string(L, LS, LS->current); | ||
| 281 | return TK_STRING; | 335 | return TK_STRING; |
| 282 | 336 | ||
| 283 | case '.': | 337 | case '.': |
| 284 | luaL_resetbuffer(L); | 338 | next(LS); |
| 285 | save_and_next(L, LS); | ||
| 286 | if (LS->current == '.') { | 339 | if (LS->current == '.') { |
| 287 | next(LS); | 340 | next(LS); |
| 288 | if (LS->current == '.') { | 341 | if (LS->current == '.') { |
| @@ -292,35 +345,14 @@ int luaX_lex (LexState *LS) { | |||
| 292 | else return TK_CONCAT; /* .. */ | 345 | else return TK_CONCAT; /* .. */ |
| 293 | } | 346 | } |
| 294 | else if (!isdigit(LS->current)) return '.'; | 347 | else if (!isdigit(LS->current)) return '.'; |
| 295 | else goto fraction; /* LS->current is a digit */ | 348 | else { |
| 349 | read_number(LS, 1); | ||
| 350 | return TK_NUMBER; | ||
| 351 | } | ||
| 296 | 352 | ||
| 297 | case '0': case '1': case '2': case '3': case '4': | 353 | case '0': case '1': case '2': case '3': case '4': |
| 298 | case '5': case '6': case '7': case '8': case '9': | 354 | case '5': case '6': case '7': case '8': case '9': |
| 299 | luaL_resetbuffer(L); | 355 | read_number(LS, 0); |
| 300 | do { | ||
| 301 | save_and_next(L, LS); | ||
| 302 | } while (isdigit(LS->current)); | ||
| 303 | if (LS->current == '.') { | ||
| 304 | save_and_next(L, LS); | ||
| 305 | if (LS->current == '.') { | ||
| 306 | save(L, '.'); | ||
| 307 | luaX_error(LS, "ambiguous syntax" | ||
| 308 | " (decimal point x string concatenation)", TK_NUMBER); | ||
| 309 | } | ||
| 310 | } | ||
| 311 | fraction: /* LUA_NUMBER */ | ||
| 312 | while (isdigit(LS->current)) | ||
| 313 | save_and_next(L, LS); | ||
| 314 | if (LS->current == 'e' || LS->current == 'E') { | ||
| 315 | save_and_next(L, LS); /* read 'E' */ | ||
| 316 | if (LS->current == '+' || LS->current == '-') | ||
| 317 | save_and_next(L, LS); /* optional exponent sign */ | ||
| 318 | while (isdigit(LS->current)) | ||
| 319 | save_and_next(L, LS); | ||
| 320 | } | ||
| 321 | save(L, '\0'); | ||
| 322 | if (!luaO_str2d(L->Mbuffer+L->Mbuffbase, &LS->t.seminfo.r)) | ||
| 323 | luaX_error(LS, "malformed number", TK_NUMBER); | ||
| 324 | return TK_NUMBER; | 356 | return TK_NUMBER; |
| 325 | 357 | ||
| 326 | case EOZ: | 358 | case EOZ: |
| @@ -337,7 +369,7 @@ int luaX_lex (LexState *LS) { | |||
| 337 | return c; | 369 | return c; |
| 338 | } | 370 | } |
| 339 | tname: { /* identifier or reserved word */ | 371 | tname: { /* identifier or reserved word */ |
| 340 | TString *ts = luaS_new(L, readname(L, LS)); | 372 | TString *ts = luaS_new(LS->L, readname(LS)); |
| 341 | if (ts->marked >= RESERVEDMARK) /* reserved word? */ | 373 | if (ts->marked >= RESERVEDMARK) /* reserved word? */ |
| 342 | return ts->marked-RESERVEDMARK+FIRST_RESERVED; | 374 | return ts->marked-RESERVEDMARK+FIRST_RESERVED; |
| 343 | LS->t.seminfo.ts = ts; | 375 | LS->t.seminfo.ts = ts; |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lobject.c,v 1.44 2000/08/09 19:16:57 roberto Exp roberto $ | 2 | ** $Id: lobject.c,v 1.45 2000/08/11 16:17:28 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 | */ |
| @@ -9,7 +9,9 @@ | |||
| 9 | 9 | ||
| 10 | #include "lua.h" | 10 | #include "lua.h" |
| 11 | 11 | ||
| 12 | #include "lmem.h" | ||
| 12 | #include "lobject.h" | 13 | #include "lobject.h" |
| 14 | #include "lstate.h" | ||
| 13 | 15 | ||
| 14 | 16 | ||
| 15 | /* | 17 | /* |
| @@ -53,6 +55,15 @@ int luaO_equalObj (const TObject *t1, const TObject *t2) { | |||
| 53 | } | 55 | } |
| 54 | 56 | ||
| 55 | 57 | ||
| 58 | char *luaO_openspace (lua_State *L, size_t n) { | ||
| 59 | if (n > L->Mbuffsize) { | ||
| 60 | luaM_reallocvector(L, L->Mbuffer, n, char); | ||
| 61 | L->Mbuffsize = n; | ||
| 62 | } | ||
| 63 | return L->Mbuffer; | ||
| 64 | } | ||
| 65 | |||
| 66 | |||
| 56 | static double expten (unsigned int e) { | 67 | static double expten (unsigned int e) { |
| 57 | double exp = 10.0; | 68 | double exp = 10.0; |
| 58 | double res = 1.0; | 69 | double res = 1.0; |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lobject.h,v 1.73 2000/08/21 14:34:43 roberto Exp roberto $ | 2 | ** $Id: lobject.h,v 1.74 2000/08/22 17:44:17 roberto Exp roberto $ |
| 3 | ** Type definitions for Lua objects | 3 | ** Type definitions for Lua objects |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -193,6 +193,7 @@ extern const TObject luaO_nilobject; | |||
| 193 | #define luaO_typename(o) luaO_typenames[ttype(o)] | 193 | #define luaO_typename(o) luaO_typenames[ttype(o)] |
| 194 | 194 | ||
| 195 | lint32 luaO_power2 (lint32 n); | 195 | lint32 luaO_power2 (lint32 n); |
| 196 | char *luaO_openspace (lua_State *L, size_t n); | ||
| 196 | 197 | ||
| 197 | int luaO_equalObj (const TObject *t1, const TObject *t2); | 198 | int luaO_equalObj (const TObject *t1, const TObject *t2); |
| 198 | int luaO_str2d (const char *s, Number *result); | 199 | int luaO_str2d (const char *s, Number *result); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstate.c,v 1.35 2000/08/31 13:30:39 roberto Exp roberto $ | 2 | ** $Id: lstate.c,v 1.36 2000/09/05 19:33:32 roberto Exp roberto $ |
| 3 | ** Global State | 3 | ** Global State |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -35,9 +35,7 @@ lua_State *lua_newstate (int stacksize) { | |||
| 35 | L->strt.hash = NULL; | 35 | L->strt.hash = NULL; |
| 36 | L->udt.hash = NULL; | 36 | L->udt.hash = NULL; |
| 37 | L->Mbuffer = NULL; | 37 | L->Mbuffer = NULL; |
| 38 | L->Mbuffbase = 0; | ||
| 39 | L->Mbuffsize = 0; | 38 | L->Mbuffsize = 0; |
| 40 | L->Mbuffnext = 0; | ||
| 41 | L->rootproto = NULL; | 39 | L->rootproto = NULL; |
| 42 | L->rootcl = NULL; | 40 | L->rootcl = NULL; |
| 43 | L->roottable = NULL; | 41 | L->roottable = NULL; |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstate.h,v 1.36 2000/08/08 20:42:07 roberto Exp roberto $ | 2 | ** $Id: lstate.h,v 1.37 2000/08/28 17:57:04 roberto Exp roberto $ |
| 3 | ** Global State | 3 | ** Global State |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -61,9 +61,7 @@ struct lua_State { | |||
| 61 | StkId Cbase; /* base for current C function */ | 61 | StkId Cbase; /* base for current C function */ |
| 62 | struct lua_longjmp *errorJmp; /* current error recover point */ | 62 | struct lua_longjmp *errorJmp; /* current error recover point */ |
| 63 | char *Mbuffer; /* global buffer */ | 63 | char *Mbuffer; /* global buffer */ |
| 64 | size_t Mbuffbase; /* current first position of Mbuffer */ | ||
| 65 | size_t Mbuffsize; /* size of Mbuffer */ | 64 | size_t Mbuffsize; /* size of Mbuffer */ |
| 66 | size_t Mbuffnext; /* next position to fill in Mbuffer */ | ||
| 67 | /* global state */ | 65 | /* global state */ |
| 68 | Proto *rootproto; /* list of all prototypes */ | 66 | Proto *rootproto; /* list of all prototypes */ |
| 69 | Closure *rootcl; /* list of all closures */ | 67 | Closure *rootcl; /* list of all closures */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstrlib.c,v 1.50 2000/08/31 20:23:40 roberto Exp roberto $ | 2 | ** $Id: lstrlib.c,v 1.51 2000/09/05 19:33:32 roberto Exp $ |
| 3 | ** Standard library for string operations and pattern-matching | 3 | ** Standard library for string operations and pattern-matching |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -18,13 +18,6 @@ | |||
| 18 | 18 | ||
| 19 | 19 | ||
| 20 | 20 | ||
| 21 | static void addnchar (lua_State *L, const char *s, size_t n) { | ||
| 22 | char *b = luaL_openspace(L, n); | ||
| 23 | memcpy(b, s, n); | ||
| 24 | luaL_addsize(L, n); | ||
| 25 | } | ||
| 26 | |||
| 27 | |||
| 28 | static int str_len (lua_State *L) { | 21 | static int str_len (lua_State *L) { |
| 29 | size_t l; | 22 | size_t l; |
| 30 | luaL_check_lstr(L, 1, &l); | 23 | luaL_check_lstr(L, 1, &l); |
| @@ -33,11 +26,6 @@ static int str_len (lua_State *L) { | |||
| 33 | } | 26 | } |
| 34 | 27 | ||
| 35 | 28 | ||
| 36 | static void closeandpush (lua_State *L) { | ||
| 37 | lua_pushlstring(L, luaL_buffer(L), luaL_getsize(L)); | ||
| 38 | } | ||
| 39 | |||
| 40 | |||
| 41 | static long posrelat (long pos, size_t len) { | 29 | static long posrelat (long pos, size_t len) { |
| 42 | /* relative string position: negative means back from end */ | 30 | /* relative string position: negative means back from end */ |
| 43 | return (pos>=0) ? pos : (long)len+pos+1; | 31 | return (pos>=0) ? pos : (long)len+pos+1; |
| @@ -61,11 +49,12 @@ static int str_sub (lua_State *L) { | |||
| 61 | static int str_lower (lua_State *L) { | 49 | static int str_lower (lua_State *L) { |
| 62 | size_t l; | 50 | size_t l; |
| 63 | size_t i; | 51 | size_t i; |
| 52 | luaL_Buffer b; | ||
| 64 | const char *s = luaL_check_lstr(L, 1, &l); | 53 | const char *s = luaL_check_lstr(L, 1, &l); |
| 65 | luaL_resetbuffer(L); | 54 | luaL_buffinit(L, &b); |
| 66 | for (i=0; i<l; i++) | 55 | for (i=0; i<l; i++) |
| 67 | luaL_addchar(L, tolower((unsigned char)(s[i]))); | 56 | luaL_putchar(&b, tolower((unsigned char)(s[i]))); |
| 68 | closeandpush(L); | 57 | luaL_pushresult(&b); |
| 69 | return 1; | 58 | return 1; |
| 70 | } | 59 | } |
| 71 | 60 | ||
| @@ -73,22 +62,24 @@ static int str_lower (lua_State *L) { | |||
| 73 | static int str_upper (lua_State *L) { | 62 | static int str_upper (lua_State *L) { |
| 74 | size_t l; | 63 | size_t l; |
| 75 | size_t i; | 64 | size_t i; |
| 65 | luaL_Buffer b; | ||
| 76 | const char *s = luaL_check_lstr(L, 1, &l); | 66 | const char *s = luaL_check_lstr(L, 1, &l); |
| 77 | luaL_resetbuffer(L); | 67 | luaL_buffinit(L, &b); |
| 78 | for (i=0; i<l; i++) | 68 | for (i=0; i<l; i++) |
| 79 | luaL_addchar(L, toupper((unsigned char)(s[i]))); | 69 | luaL_putchar(&b, toupper((unsigned char)(s[i]))); |
| 80 | closeandpush(L); | 70 | luaL_pushresult(&b); |
| 81 | return 1; | 71 | return 1; |
| 82 | } | 72 | } |
| 83 | 73 | ||
| 84 | static int str_rep (lua_State *L) { | 74 | static int str_rep (lua_State *L) { |
| 85 | size_t l; | 75 | size_t l; |
| 76 | luaL_Buffer b; | ||
| 86 | const char *s = luaL_check_lstr(L, 1, &l); | 77 | const char *s = luaL_check_lstr(L, 1, &l); |
| 87 | int n = luaL_check_int(L, 2); | 78 | int n = luaL_check_int(L, 2); |
| 88 | luaL_resetbuffer(L); | 79 | luaL_buffinit(L, &b); |
| 89 | while (n-- > 0) | 80 | while (n-- > 0) |
| 90 | addnchar(L, s, l); | 81 | luaL_addlstring(&b, s, l); |
| 91 | closeandpush(L); | 82 | luaL_pushresult(&b); |
| 92 | return 1; | 83 | return 1; |
| 93 | } | 84 | } |
| 94 | 85 | ||
| @@ -106,13 +97,14 @@ static int str_byte (lua_State *L) { | |||
| 106 | static int str_char (lua_State *L) { | 97 | static int str_char (lua_State *L) { |
| 107 | int n = lua_gettop(L); /* number of arguments */ | 98 | int n = lua_gettop(L); /* number of arguments */ |
| 108 | int i; | 99 | int i; |
| 109 | luaL_resetbuffer(L); | 100 | luaL_Buffer b; |
| 101 | luaL_buffinit(L, &b); | ||
| 110 | for (i=1; i<=n; i++) { | 102 | for (i=1; i<=n; i++) { |
| 111 | int c = luaL_check_int(L, i); | 103 | int c = luaL_check_int(L, i); |
| 112 | luaL_arg_check(L, (unsigned char)c == c, i, "invalid value"); | 104 | luaL_arg_check(L, (unsigned char)c == c, i, "invalid value"); |
| 113 | luaL_addchar(L, (unsigned char)c); | 105 | luaL_putchar(&b, (unsigned char)c); |
| 114 | } | 106 | } |
| 115 | closeandpush(L); | 107 | luaL_pushresult(&b); |
| 116 | return 1; | 108 | return 1; |
| 117 | } | 109 | } |
| 118 | 110 | ||
| @@ -445,43 +437,37 @@ static int str_find (lua_State *L) { | |||
| 445 | } | 437 | } |
| 446 | 438 | ||
| 447 | 439 | ||
| 448 | static void add_s (lua_State *L, struct Capture *cap) { | 440 | static void add_s (lua_State *L, luaL_Buffer *b, struct Capture *cap) { |
| 449 | if (lua_isstring(L, 3)) { | 441 | if (lua_isstring(L, 3)) { |
| 450 | const char *news = lua_tostring(L, 3); | 442 | const char *news = lua_tostring(L, 3); |
| 451 | size_t l = lua_strlen(L, 3); | 443 | size_t l = lua_strlen(L, 3); |
| 452 | size_t i; | 444 | size_t i; |
| 453 | for (i=0; i<l; i++) { | 445 | for (i=0; i<l; i++) { |
| 454 | if (news[i] != ESC) | 446 | if (news[i] != ESC) |
| 455 | luaL_addchar(L, news[i]); | 447 | luaL_putchar(b, news[i]); |
| 456 | else { | 448 | else { |
| 457 | i++; /* skip ESC */ | 449 | i++; /* skip ESC */ |
| 458 | if (!isdigit((unsigned char)news[i])) | 450 | if (!isdigit((unsigned char)news[i])) |
| 459 | luaL_addchar(L, news[i]); | 451 | luaL_putchar(b, news[i]); |
| 460 | else { | 452 | else { |
| 461 | int level = check_capture(L, news[i], cap); | 453 | int level = check_capture(L, news[i], cap); |
| 462 | addnchar(L, cap->capture[level].init, cap->capture[level].len); | 454 | luaL_addlstring(b, cap->capture[level].init, cap->capture[level].len); |
| 463 | } | 455 | } |
| 464 | } | 456 | } |
| 465 | } | 457 | } |
| 466 | } | 458 | } |
| 467 | else { /* is a function */ | 459 | else { /* is a function */ |
| 468 | int status; | 460 | int status; |
| 469 | size_t oldbuff; | ||
| 470 | int n; | 461 | int n; |
| 471 | const char *s; | ||
| 472 | lua_pushvalue(L, 3); | 462 | lua_pushvalue(L, 3); |
| 473 | n = push_captures(L, cap); | 463 | n = push_captures(L, cap); |
| 474 | /* function may use buffer, so save it and create a new one */ | ||
| 475 | oldbuff = luaL_newbuffer(L, 0); | ||
| 476 | status = lua_call(L, n, 1); | 464 | status = lua_call(L, n, 1); |
| 477 | /* restore old buffer */ | ||
| 478 | luaL_oldbuffer(L, oldbuff); | ||
| 479 | if (status != 0) | 465 | if (status != 0) |
| 480 | lua_error(L, NULL); | 466 | lua_error(L, NULL); /* propagate error */ |
| 481 | s = lua_tostring(L, -1); | 467 | if (lua_isstring(L, -1)) |
| 482 | if (s) | 468 | luaL_addvalue(b); /* add return to accumulated result */ |
| 483 | addnchar(L, lua_tostring(L, -1), lua_strlen(L, -1)); | 469 | else |
| 484 | lua_pop(L, 1); /* pop function result */ | 470 | lua_pop(L, 1); /* function result is not a string: pop it */ |
| 485 | } | 471 | } |
| 486 | } | 472 | } |
| 487 | 473 | ||
| @@ -494,10 +480,11 @@ static int str_gsub (lua_State *L) { | |||
| 494 | int anchor = (*p == '^') ? (p++, 1) : 0; | 480 | int anchor = (*p == '^') ? (p++, 1) : 0; |
| 495 | int n = 0; | 481 | int n = 0; |
| 496 | struct Capture cap; | 482 | struct Capture cap; |
| 483 | luaL_Buffer b; | ||
| 497 | luaL_arg_check(L, | 484 | luaL_arg_check(L, |
| 498 | lua_gettop(L) >= 3 && (lua_isstring(L, 3) || lua_isfunction(L, 3)), | 485 | lua_gettop(L) >= 3 && (lua_isstring(L, 3) || lua_isfunction(L, 3)), |
| 499 | 3, "string or function expected"); | 486 | 3, "string or function expected"); |
| 500 | luaL_resetbuffer(L); | 487 | luaL_buffinit(L, &b); |
| 501 | cap.src_end = src+srcl; | 488 | cap.src_end = src+srcl; |
| 502 | while (n < max_s) { | 489 | while (n < max_s) { |
| 503 | const char *e; | 490 | const char *e; |
| @@ -505,17 +492,17 @@ static int str_gsub (lua_State *L) { | |||
| 505 | e = match(L, src, p, &cap); | 492 | e = match(L, src, p, &cap); |
| 506 | if (e) { | 493 | if (e) { |
| 507 | n++; | 494 | n++; |
| 508 | add_s(L, &cap); | 495 | add_s(L, &b, &cap); |
| 509 | } | 496 | } |
| 510 | if (e && e>src) /* non empty match? */ | 497 | if (e && e>src) /* non empty match? */ |
| 511 | src = e; /* skip it */ | 498 | src = e; /* skip it */ |
| 512 | else if (src < cap.src_end) | 499 | else if (src < cap.src_end) |
| 513 | luaL_addchar(L, *src++); | 500 | luaL_putchar(&b, *src++); |
| 514 | else break; | 501 | else break; |
| 515 | if (anchor) break; | 502 | if (anchor) break; |
| 516 | } | 503 | } |
| 517 | addnchar(L, src, cap.src_end-src); | 504 | luaL_addlstring(&b, src, cap.src_end-src); |
| 518 | closeandpush(L); | 505 | luaL_pushresult(&b); |
| 519 | lua_pushnumber(L, n); /* number of substitutions */ | 506 | lua_pushnumber(L, n); /* number of substitutions */ |
| 520 | return 2; | 507 | return 2; |
| 521 | } | 508 | } |
| @@ -523,40 +510,43 @@ static int str_gsub (lua_State *L) { | |||
| 523 | /* }====================================================== */ | 510 | /* }====================================================== */ |
| 524 | 511 | ||
| 525 | 512 | ||
| 526 | static void luaI_addquoted (lua_State *L, int arg) { | 513 | static void luaI_addquoted (lua_State *L, luaL_Buffer *b, int arg) { |
| 527 | size_t l; | 514 | size_t l; |
| 528 | const char *s = luaL_check_lstr(L, arg, &l); | 515 | const char *s = luaL_check_lstr(L, arg, &l); |
| 529 | luaL_addchar(L, '"'); | 516 | luaL_putchar(b, '"'); |
| 530 | while (l--) { | 517 | while (l--) { |
| 531 | switch (*s) { | 518 | switch (*s) { |
| 532 | case '"': case '\\': case '\n': | 519 | case '"': case '\\': case '\n': |
| 533 | luaL_addchar(L, '\\'); | 520 | luaL_putchar(b, '\\'); |
| 534 | luaL_addchar(L, *s); | 521 | luaL_putchar(b, *s); |
| 535 | break; | 522 | break; |
| 536 | case '\0': addnchar(L, "\\000", 4); break; | 523 | case '\0': luaL_addlstring(b, "\\000", 4); break; |
| 537 | default: luaL_addchar(L, *s); | 524 | default: luaL_putchar(b, *s); |
| 538 | } | 525 | } |
| 539 | s++; | 526 | s++; |
| 540 | } | 527 | } |
| 541 | luaL_addchar(L, '"'); | 528 | luaL_putchar(b, '"'); |
| 542 | } | 529 | } |
| 543 | 530 | ||
| 531 | /* maximum size of each formated item (> len(format('%99.99f', -1e308))) */ | ||
| 532 | #define MAX_ITEM 512 | ||
| 544 | /* maximum size of each format specification (such as '%-099.99d') */ | 533 | /* maximum size of each format specification (such as '%-099.99d') */ |
| 545 | #define MAX_FORMAT 20 /* arbitrary limit */ | 534 | #define MAX_FORMAT 20 |
| 546 | 535 | ||
| 547 | static int str_format (lua_State *L) { | 536 | static int str_format (lua_State *L) { |
| 548 | int arg = 1; | 537 | int arg = 1; |
| 549 | const char *strfrmt = luaL_check_string(L, arg); | 538 | const char *strfrmt = luaL_check_string(L, arg); |
| 550 | luaL_resetbuffer(L); | 539 | luaL_Buffer b; |
| 540 | luaL_buffinit(L, &b); | ||
| 551 | while (*strfrmt) { | 541 | while (*strfrmt) { |
| 552 | if (*strfrmt != '%') | 542 | if (*strfrmt != '%') |
| 553 | luaL_addchar(L, *strfrmt++); | 543 | luaL_putchar(&b, *strfrmt++); |
| 554 | else if (*++strfrmt == '%') | 544 | else if (*++strfrmt == '%') |
| 555 | luaL_addchar(L, *strfrmt++); /* %% */ | 545 | luaL_putchar(&b, *strfrmt++); /* %% */ |
| 556 | else { /* format item */ | 546 | else { /* format item */ |
| 557 | struct Capture cap; | 547 | struct Capture cap; |
| 558 | char form[MAX_FORMAT]; /* to store the format ('%...') */ | 548 | char form[MAX_FORMAT]; /* to store the format ('%...') */ |
| 559 | char *buff; /* to store the formatted item */ | 549 | char buff[MAX_ITEM]; /* to store the formatted item */ |
| 560 | const char *initf = strfrmt; | 550 | const char *initf = strfrmt; |
| 561 | form[0] = '%'; | 551 | form[0] = '%'; |
| 562 | if (isdigit((unsigned char)*initf) && *(initf+1) == '$') { | 552 | if (isdigit((unsigned char)*initf) && *(initf+1) == '$') { |
| @@ -572,7 +562,6 @@ static int str_format (lua_State *L) { | |||
| 572 | lua_error(L, "invalid format (width or precision too long)"); | 562 | lua_error(L, "invalid format (width or precision too long)"); |
| 573 | strncpy(form+1, initf, strfrmt-initf+1); /* +1 to include conversion */ | 563 | strncpy(form+1, initf, strfrmt-initf+1); /* +1 to include conversion */ |
| 574 | form[strfrmt-initf+2] = 0; | 564 | form[strfrmt-initf+2] = 0; |
| 575 | buff = luaL_openspace(L, 512); /* 512 > len(format('%99.99f', -1e308)) */ | ||
| 576 | switch (*strfrmt++) { | 565 | switch (*strfrmt++) { |
| 577 | case 'c': case 'd': case 'i': | 566 | case 'c': case 'd': case 'i': |
| 578 | sprintf(buff, form, luaL_check_int(L, arg)); | 567 | sprintf(buff, form, luaL_check_int(L, arg)); |
| @@ -584,7 +573,7 @@ static int str_format (lua_State *L) { | |||
| 584 | sprintf(buff, form, luaL_check_number(L, arg)); | 573 | sprintf(buff, form, luaL_check_number(L, arg)); |
| 585 | break; | 574 | break; |
| 586 | case 'q': | 575 | case 'q': |
| 587 | luaI_addquoted(L, arg); | 576 | luaI_addquoted(L, &b, arg); |
| 588 | continue; /* skip the "addsize" at the end */ | 577 | continue; /* skip the "addsize" at the end */ |
| 589 | case 's': { | 578 | case 's': { |
| 590 | size_t l; | 579 | size_t l; |
| @@ -592,7 +581,8 @@ static int str_format (lua_State *L) { | |||
| 592 | if (cap.capture[1].len == 0 && l >= 100) { | 581 | if (cap.capture[1].len == 0 && l >= 100) { |
| 593 | /* no precision and string is too long to be formatted; | 582 | /* no precision and string is too long to be formatted; |
| 594 | keep original string */ | 583 | keep original string */ |
| 595 | addnchar(L, s, l); | 584 | lua_pushvalue(L, arg); |
| 585 | luaL_addvalue(&b); | ||
| 596 | continue; /* skip the "addsize" at the end */ | 586 | continue; /* skip the "addsize" at the end */ |
| 597 | } | 587 | } |
| 598 | else { | 588 | else { |
| @@ -603,10 +593,10 @@ static int str_format (lua_State *L) { | |||
| 603 | default: /* also treat cases 'pnLlh' */ | 593 | default: /* also treat cases 'pnLlh' */ |
| 604 | lua_error(L, "invalid option in `format'"); | 594 | lua_error(L, "invalid option in `format'"); |
| 605 | } | 595 | } |
| 606 | luaL_addsize(L, strlen(buff)); | 596 | luaL_addlstring(&b, buff, strlen(buff)); |
| 607 | } | 597 | } |
| 608 | } | 598 | } |
| 609 | closeandpush(L); /* push the result */ | 599 | luaL_pushresult(&b); |
| 610 | return 1; | 600 | return 1; |
| 611 | } | 601 | } |
| 612 | 602 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lundump.c,v 1.29 2000/06/28 14:12:55 lhf Exp lhf $ | 2 | ** $Id: lundump.c,v 1.27 2000/09/04 18:53:41 roberto Exp roberto $ |
| 3 | ** load bytecodes from files | 3 | ** load bytecodes from files |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -86,7 +86,7 @@ static TString* LoadString (lua_State* L, ZIO* Z, int swap) | |||
| 86 | return NULL; | 86 | return NULL; |
| 87 | else | 87 | else |
| 88 | { | 88 | { |
| 89 | char* s=luaL_openspace(L,size); | 89 | char* s=luaO_openspace(L,size); |
| 90 | LoadBlock(L,s,size,Z); | 90 | LoadBlock(L,s,size,Z); |
| 91 | return luaS_newlstr(L,s,size-1); /* remove trailing '\0' */ | 91 | return luaS_newlstr(L,s,size-1); /* remove trailing '\0' */ |
| 92 | } | 92 | } |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lvm.c,v 1.133 2000/08/31 21:02:55 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 1.134 2000/09/05 19:33:32 roberto Exp roberto $ |
| 3 | ** Lua virtual machine | 3 | ** Lua virtual machine |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -12,7 +12,6 @@ | |||
| 12 | #include "lua.h" | 12 | #include "lua.h" |
| 13 | 13 | ||
| 14 | #include "lapi.h" | 14 | #include "lapi.h" |
| 15 | #include "lauxlib.h" | ||
| 16 | #include "ldebug.h" | 15 | #include "ldebug.h" |
| 17 | #include "ldo.h" | 16 | #include "ldo.h" |
| 18 | #include "lfunc.h" | 17 | #include "lfunc.h" |
| @@ -300,7 +299,7 @@ void luaV_strconc (lua_State *L, int total, StkId top) { | |||
| 300 | n++; | 299 | n++; |
| 301 | } | 300 | } |
| 302 | if (tl > MAX_SIZET) lua_error(L, "string size overflow"); | 301 | if (tl > MAX_SIZET) lua_error(L, "string size overflow"); |
| 303 | buffer = luaL_openspace(L, tl); | 302 | buffer = luaO_openspace(L, tl); |
| 304 | tl = 0; | 303 | tl = 0; |
| 305 | for (i=n; i>0; i--) { /* concat all strings */ | 304 | for (i=n; i>0; i--) { /* concat all strings */ |
| 306 | size_t l = tsvalue(top-i)->u.s.len; | 305 | size_t l = tsvalue(top-i)->u.s.len; |
