aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-09-11 14:38:42 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-09-11 14:38:42 -0300
commit787a78f83e0484c9e9698189982e2f309808fae8 (patch)
tree0682eddf4ea5a49bf5078bac937a36f90057df57
parent70c8a310925d6c41c3ef4f7feeae604a4c9a3a95 (diff)
downloadlua-787a78f83e0484c9e9698189982e2f309808fae8.tar.gz
lua-787a78f83e0484c9e9698189982e2f309808fae8.tar.bz2
lua-787a78f83e0484c9e9698189982e2f309808fae8.zip
new scheme for buffers
-rw-r--r--lauxlib.c97
-rw-r--r--lauxlib.h47
-rw-r--r--ldo.c5
-rw-r--r--lgc.c8
-rw-r--r--liolib.c87
-rw-r--r--llex.c196
-rw-r--r--lobject.c13
-rw-r--r--lobject.h3
-rw-r--r--lstate.c4
-rw-r--r--lstate.h4
-rw-r--r--lstrlib.c114
-rw-r--r--lundump.c4
-rw-r--r--lvm.c5
13 files changed, 376 insertions, 211 deletions
diff --git a/lauxlib.c b/lauxlib.c
index 2c54bd02..84ccb3b9 100644
--- a/lauxlib.c
+++ b/lauxlib.c
@@ -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
143void 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
157static 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
169static 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
190char *luaL_prepbuffer (luaL_Buffer *B) {
191 if (emptybuffer(B))
192 adjuststack(B);
193 return B->buffer;
194}
195
196
197void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) {
198 while (l--)
199 luaL_putchar(B, *s++);
200}
201
202
203void 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
213void 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
230void 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/* }====================================================== */
diff --git a/lauxlib.h b/lauxlib.h
index 8e3fea5c..de717da5 100644
--- a/lauxlib.h
+++ b/lauxlib.h
@@ -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);
34void luaL_verror (lua_State *L, const char *fmt, ...); 35void luaL_verror (lua_State *L, const char *fmt, ...);
35int luaL_findstring (const char *name, const char *const list[]); 36int luaL_findstring (const char *name, const char *const list[]);
36void luaL_chunkid (char *out, const char *source, int len); 37void luaL_chunkid (char *out, const char *source, int len);
37void luaL_filesource (char *out, const char *filename, int len);
38 38
39 39
40char *luaL_openspace (lua_State *L, size_t size);
41void luaL_resetbuffer (lua_State *L);
42void luaL_addchar (lua_State *L, int c);
43size_t luaL_getsize (lua_State *L);
44void luaL_addsize (lua_State *L, size_t n);
45size_t luaL_newbuffer (lua_State *L, size_t size);
46void luaL_oldbuffer (lua_State *L, size_t old);
47char *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
68typedef 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
81void luaL_buffinit (lua_State *L, luaL_Buffer *B);
82char *luaL_prepbuffer (luaL_Buffer *B);
83void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l);
84void luaL_addvalue (luaL_Buffer *B);
85void luaL_pushresult (luaL_Buffer *B);
86
87
88/* }====================================================== */
89
90
67#endif 91#endif
68 92
93
diff --git a/ldo.c b/ldo.c
index a06fa138..1fd993c7 100644
--- a/ldo.c
+++ b/ldo.c
@@ -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);
diff --git a/lgc.c b/lgc.c
index f6768dd2..5329e558 100644
--- a/lgc.c
+++ b/lgc.c
@@ -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
336long lua_collectgarbage (lua_State *L, long limit) { 338long 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);
diff --git a/liolib.c b/liolib.c
index 885db9bd..db9f36d6 100644
--- a/liolib.c
+++ b/liolib.c
@@ -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
311static void read_word (lua_State *L, FILE *f) { 311static 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
325static int read_line (lua_State *L, FILE *f) { 326static 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
343static void read_file (lua_State *L, FILE *f) { 347static 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
353static int read_chars (lua_State *L, FILE *f, size_t n) { 364static 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}
diff --git a/llex.c b/llex.c
index 6a9039d1..d16cb99f 100644
--- a/llex.c
+++ b/llex.c
@@ -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 */
35static const char *const token2string [] = { 32static const char *const token2string [] = {
@@ -70,10 +67,8 @@ void luaX_syntaxerror (LexState *ls, const char *s, const char *token) {
70void luaX_error (LexState *ls, const char *s, int token) { 67void 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
99static 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
109static void inclinenumber (LexState *LS) { 94static 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
142static void read_long_string (lua_State *L, LexState *LS) { 136static 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 */
150static 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
187static 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
178static void read_string (lua_State *L, LexState *LS, int del) { 230static 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
224int luaX_lex (LexState *LS) { 282int 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;
diff --git a/lobject.c b/lobject.c
index c833e921..7f3d71fc 100644
--- a/lobject.c
+++ b/lobject.c
@@ -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
58char *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
56static double expten (unsigned int e) { 67static 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;
diff --git a/lobject.h b/lobject.h
index f2d60760..d36391a6 100644
--- a/lobject.h
+++ b/lobject.h
@@ -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
195lint32 luaO_power2 (lint32 n); 195lint32 luaO_power2 (lint32 n);
196char *luaO_openspace (lua_State *L, size_t n);
196 197
197int luaO_equalObj (const TObject *t1, const TObject *t2); 198int luaO_equalObj (const TObject *t1, const TObject *t2);
198int luaO_str2d (const char *s, Number *result); 199int luaO_str2d (const char *s, Number *result);
diff --git a/lstate.c b/lstate.c
index f5d5b67c..1e35e467 100644
--- a/lstate.c
+++ b/lstate.c
@@ -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;
diff --git a/lstate.h b/lstate.h
index 65e4c6ef..66ae964d 100644
--- a/lstate.h
+++ b/lstate.h
@@ -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 */
diff --git a/lstrlib.c b/lstrlib.c
index 6cdd87da..89114666 100644
--- a/lstrlib.c
+++ b/lstrlib.c
@@ -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
21static 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
28static int str_len (lua_State *L) { 21static 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
36static void closeandpush (lua_State *L) {
37 lua_pushlstring(L, luaL_buffer(L), luaL_getsize(L));
38}
39
40
41static long posrelat (long pos, size_t len) { 29static 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) {
61static int str_lower (lua_State *L) { 49static 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) {
73static int str_upper (lua_State *L) { 62static 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
84static int str_rep (lua_State *L) { 74static 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) {
106static int str_char (lua_State *L) { 97static 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
448static void add_s (lua_State *L, struct Capture *cap) { 440static 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
526static void luaI_addquoted (lua_State *L, int arg) { 513static 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
547static int str_format (lua_State *L) { 536static 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
diff --git a/lundump.c b/lundump.c
index b42f441b..95690033 100644
--- a/lundump.c
+++ b/lundump.c
@@ -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 }
diff --git a/lvm.c b/lvm.c
index a8e81dd5..d842b3ba 100644
--- a/lvm.c
+++ b/lvm.c
@@ -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;