diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-09-11 14:38:42 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-09-11 14:38:42 -0300 |
commit | 787a78f83e0484c9e9698189982e2f309808fae8 (patch) | |
tree | 0682eddf4ea5a49bf5078bac937a36f90057df57 | |
parent | 70c8a310925d6c41c3ef4f7feeae604a4c9a3a95 (diff) | |
download | lua-787a78f83e0484c9e9698189982e2f309808fae8.tar.gz lua-787a78f83e0484c9e9698189982e2f309808fae8.tar.bz2 lua-787a78f83e0484c9e9698189982e2f309808fae8.zip |
new scheme for buffers
-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; |