Browse Source

new scheme for buffers

v5-2
Roberto Ierusalimschy 25 years ago
parent
commit
787a78f83e
  1. 97
      lauxlib.c
  2. 47
      lauxlib.h
  3. 5
      ldo.c
  4. 8
      lgc.c
  5. 87
      liolib.c
  6. 196
      llex.c
  7. 13
      lobject.c
  8. 3
      lobject.h
  9. 4
      lstate.c
  10. 4
      lstate.h
  11. 114
      lstrlib.c
  12. 4
      lundump.c
  13. 5
      lvm.c

97
lauxlib.c

@ -1,5 +1,5 @@
/*
** $Id: lauxlib.c,v 1.32 2000/08/29 14:33:31 roberto Exp roberto $
** $Id: lauxlib.c,v 1.33 2000/08/29 20:43:28 roberto Exp roberto $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
@ -140,8 +140,97 @@ void luaL_chunkid (char *out, const char *source, int len) {
}
void luaL_filesource (char *out, const char *filename, int len) {
if (filename == NULL) filename = "(stdin)";
sprintf(out, "@%.*s", len-2, filename); /* -2 for '@' and '\0' */
/*
** {======================================================
** Generic Buffer manipulation
** =======================================================
*/
#define buffempty(B) ((B)->p == (B)->buffer)
#define bufflen(B) ((B)->p - (B)->buffer)
#define bufffree(B) ((size_t)(LUAL_BUFFERSIZE - bufflen(B)))
#define LIMIT (LUA_MINSTACK/2)
static int emptybuffer (luaL_Buffer *B) {
size_t l = bufflen(B);
if (l == 0) return 0; /* put nothing on stack */
else {
lua_pushlstring(B->L, B->buffer, l);
B->p = B->buffer;
B->level++;
return 1;
}
}
static void adjuststack (luaL_Buffer *B) {
if (B->level > 1) {
lua_State *L = B->L;
int toget = 1; /* number of levels to concat */
size_t toplen = lua_strlen(L, -1);
do {
size_t l = lua_strlen(L, -(toget+1));
if (B->level - toget + 1 >= LIMIT || toplen > l) {
toplen += l;
toget++;
}
else break;
} while (toget < B->level);
if (toget >= 2) {
lua_concat(L, toget);
B->level = B->level - toget + 1;
}
}
}
char *luaL_prepbuffer (luaL_Buffer *B) {
if (emptybuffer(B))
adjuststack(B);
return B->buffer;
}
void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) {
while (l--)
luaL_putchar(B, *s++);
}
void luaL_pushresult (luaL_Buffer *B) {
emptybuffer(B);
if (B->level == 0)
lua_pushlstring(B->L, NULL, 0);
else if (B->level > 1)
lua_concat(B->L, B->level);
B->level = 1;
}
void luaL_addvalue (luaL_Buffer *B) {
lua_State *L = B->L;
size_t vl = lua_strlen(L, -1);
if (vl <= bufffree(B)) { /* fit into buffer? */
memcpy(B->p, lua_tostring(L, -1), vl); /* put it there */
B->p += vl;
lua_pop(L, 1); /* remove from stack */
}
else {
if (emptybuffer(B))
lua_insert(L, -2); /* put buffer before new value */
B->level++; /* add new value into B stack */
adjuststack(B);
}
}
void luaL_buffinit (lua_State *L, luaL_Buffer *B) {
B->L = L;
B->p = B->buffer;
B->level = 0;
}
/* }====================================================== */

47
lauxlib.h

@ -1,5 +1,5 @@
/*
** $Id: lauxlib.h,v 1.21 2000/08/29 20:43:28 roberto Exp roberto $
** $Id: lauxlib.h,v 1.22 2000/09/04 18:27:32 roberto Exp roberto $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
@ -10,6 +10,7 @@
#include <stddef.h>
#include <stdio.h>
#include "lua.h"
@ -34,18 +35,8 @@ void luaL_checktype (lua_State *L, int narg, const char *tname);
void luaL_verror (lua_State *L, const char *fmt, ...);
int luaL_findstring (const char *name, const char *const list[]);
void luaL_chunkid (char *out, const char *source, int len);
void luaL_filesource (char *out, const char *filename, int len);
char *luaL_openspace (lua_State *L, size_t size);
void luaL_resetbuffer (lua_State *L);
void luaL_addchar (lua_State *L, int c);
size_t luaL_getsize (lua_State *L);
void luaL_addsize (lua_State *L, size_t n);
size_t luaL_newbuffer (lua_State *L, size_t size);
void luaL_oldbuffer (lua_State *L, size_t old);
char *luaL_buffer (lua_State *L);
/*
** ===============================================================
@ -64,5 +55,39 @@ char *luaL_buffer (lua_State *L);
#define luaL_openl(L,a) luaL_openlib(L, a, (sizeof(a)/sizeof(a[0])))
/*
** {======================================================
** Generic Buffer manipulation
** =======================================================
*/
#define LUAL_BUFFERSIZE BUFSIZ
typedef struct luaL_Buffer {
char *p; /* current position in buffer */
int level;
lua_State *L;
char buffer[LUAL_BUFFERSIZE];
} luaL_Buffer;
#define luaL_putchar(B,c) \
((void)((B)->p < &(B)->buffer[LUAL_BUFFERSIZE] || luaL_prepbuffer(B)), \
(*(B)->p++ = (char)(c)))
#define luaL_addsize(B,n) ((B)->p += (n))
void luaL_buffinit (lua_State *L, luaL_Buffer *B);
char *luaL_prepbuffer (luaL_Buffer *B);
void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l);
void luaL_addvalue (luaL_Buffer *B);
void luaL_pushresult (luaL_Buffer *B);
/* }====================================================== */
#endif

5
ldo.c

@ -1,5 +1,5 @@
/*
** $Id: ldo.c,v 1.92 2000/08/31 13:31:44 roberto Exp roberto $
** $Id: ldo.c,v 1.93 2000/09/04 18:52:51 roberto Exp roberto $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
@ -293,7 +293,8 @@ static int parse_file (lua_State *L, const char *filename) {
int c; /* look ahead char */
FILE *f = (filename == NULL) ? stdin : fopen(filename, "r");
if (f == NULL) return LUA_ERRFILE; /* unable to open file */
luaL_filesource(source, filename, sizeof(source));
if (filename == NULL) filename = "(stdin)";
sprintf(source, "@%.*s", (int)sizeof(source)-2, filename);
c = fgetc(f);
ungetc(c, f);
bin = (c == ID_CHUNK);

8
lgc.c

@ -1,5 +1,5 @@
/*
** $Id: lgc.c,v 1.63 2000/08/22 17:44:17 roberto Exp roberto $
** $Id: lgc.c,v 1.64 2000/08/28 17:57:04 roberto Exp roberto $
** Garbage Collector
** See Copyright Notice in lua.h
*/
@ -333,6 +333,8 @@ void luaC_collect (lua_State *L, int all) {
}
#define MINBUFFER 256
long lua_collectgarbage (lua_State *L, long limit) {
unsigned long recovered = L->nblocks; /* to subtract `nblocks' after gc */
markall(L);
@ -340,8 +342,8 @@ long lua_collectgarbage (lua_State *L, long limit) {
luaC_collect(L, 0);
recovered = recovered - L->nblocks;
L->GCthreshold = (limit == 0) ? 2*L->nblocks : L->nblocks+limit;
if (L->Mbuffsize > L->Mbuffnext*4) { /* is buffer too big? */
L->Mbuffsize /= 2; /* still larger than Mbuffnext*2 */
if (L->Mbuffsize > MINBUFFER*2) { /* is buffer too big? */
L->Mbuffsize /= 2; /* still larger than MINBUFFER */
luaM_reallocvector(L, L->Mbuffer, L->Mbuffsize, char);
}
callgcTM(L, &luaO_nilobject);

87
liolib.c

@ -1,5 +1,5 @@
/*
** $Id: liolib.c,v 1.76 2000/08/31 20:23:40 roberto Exp roberto $
** $Id: liolib.c,v 1.77 2000/09/05 19:33:32 roberto Exp $
** Standard I/O (and system) library
** See Copyright Notice in lua.h
*/
@ -263,7 +263,7 @@ static int read_pattern (lua_State *L, FILE *f, const char *p) {
if (c == NEED_OTHER) c = getc(f);
m = (c==EOF) ? 0 : luaI_singlematch(c, p, ep);
if (m) {
if (!inskip) luaL_addchar(L, c);
if (!inskip) luaL_putchar(L, c);
c = NEED_OTHER;
}
switch (*ep) {
@ -274,7 +274,7 @@ static int read_pattern (lua_State *L, FILE *f, const char *p) {
while (m) { /* reads the same item until it fails */
c = getc(f);
m = (c==EOF) ? 0 : luaI_singlematch(c, p, ep);
if (m && !inskip) luaL_addchar(L, c);
if (m && !inskip) luaL_putchar(L, c);
}
/* go through to continue reading the pattern */
case '?': /* optional */
@ -308,53 +308,74 @@ static int read_number (lua_State *L, FILE *f) {
}
static void read_word (lua_State *L, FILE *f) {
static int read_word (lua_State *L, FILE *f) {
int c;
luaL_Buffer b;
luaL_buffinit(L, &b);
do { c = fgetc(f); } while (isspace(c)); /* skip spaces */
while (c != EOF && !isspace(c)) {
luaL_addchar(L, c);
luaL_putchar(&b, c);
c = fgetc(f);
}
ungetc(c, f);
luaL_pushresult(&b); /* close buffer */
return (lua_strlen(L, 1) > 0);
}
#define HUNK_LINE 256
#define HUNK_FILE BUFSIZ
static int read_line (lua_State *L, FILE *f) {
int n;
char *b;
int n = 0;
luaL_Buffer b;
luaL_buffinit(L, &b);
for (;;) {
b = luaL_openspace(L, HUNK_LINE);
if (!fgets(b, HUNK_LINE, f)) return 0; /* read fails */
n = strlen(b);
if (b[n-1] != '\n')
luaL_addsize(L, n);
char *p = luaL_prepbuffer(&b);
if (!fgets(p, LUAL_BUFFERSIZE, f)) /* read fails? */
break;
n = strlen(p);
if (p[n-1] != '\n')
luaL_addsize(&b, n);
else {
luaL_addsize(L, n-1); /* do not add the `\n' */
luaL_addsize(&b, n-1); /* do not add the `\n' */
break;
}
}
return 1;
luaL_pushresult(&b); /* close buffer */
return (n > 0); /* read something? */
}
static void read_file (lua_State *L, FILE *f) {
size_t n;
do {
char *b = luaL_openspace(L, HUNK_FILE);
n = fread(b, sizeof(char), HUNK_FILE, f);
luaL_addsize(L, n);
} while (n==HUNK_FILE);
size_t len = 0;
size_t size = BUFSIZ;
char *buffer = NULL;
for (;;) {
buffer = (char *)realloc(buffer, size);
if (buffer == NULL)
lua_error(L, "not enough memory to read a file");
len += fread(buffer+len, sizeof(char), size-len, f);
if (len < size) break; /* did not read all it could */
size *= 2;
}
lua_pushlstring(L, buffer, len);
free(buffer);
}
static int read_chars (lua_State *L, FILE *f, size_t n) {
char *b = luaL_openspace(L, n);
size_t n1 = fread(b, sizeof(char), n, f);
luaL_addsize(L, n1);
return (n == n1);
char *buffer;
size_t n1;
char statbuff[BUFSIZ];
if (n <= BUFSIZ)
buffer = statbuff;
else {
buffer = (char *)malloc(n);
if (buffer == NULL)
lua_error(L, "not enough memory to read a file");
}
n1 = fread(buffer, sizeof(char), n, f);
lua_pushlstring(L, buffer, n1);
if (buffer != statbuff) free(buffer);
return (n1 > 0 || n == 0);
}
@ -375,9 +396,7 @@ static int io_read (lua_State *L) {
else
luaL_checkstack(L, lastarg-firstarg+1, "too many arguments");
for (n = firstarg; n<=lastarg; n++) {
size_t l;
int success;
luaL_resetbuffer(L);
if (lua_isnumber(L, n))
success = read_chars(L, f, (size_t)lua_tonumber(L, n));
else {
@ -397,8 +416,7 @@ static int io_read (lua_State *L) {
success = 1; /* always success */
break;
case 'w': /* word */
read_word(L, f);
success = 0; /* must read something to succeed */
success = read_word(L, f);
break;
default:
luaL_argerror(L, n, "invalid format");
@ -406,9 +424,10 @@ static int io_read (lua_State *L) {
}
}
}
l = luaL_getsize(L);
if (!success && l==0) break; /* read fails */
lua_pushlstring(L, luaL_buffer(L), l);
if (!success) {
lua_pop(L, 1); /* remove last result */
break; /* read fails */
}
} endloop:
return n - firstarg;
}

196
llex.c

@ -1,5 +1,5 @@
/*
** $Id: llex.c,v 1.67 2000/08/09 19:16:57 roberto Exp roberto $
** $Id: llex.c,v 1.68 2000/08/22 20:07:56 roberto Exp $
** Lexical Analyzer
** See Copyright Notice in lua.h
*/
@ -27,9 +27,6 @@
#define next(LS) (LS->current = zgetc(LS->z))
#define save(L, c) luaL_addchar(L, c)
#define save_and_next(L, LS) (save(L, LS->current), next(LS))
/* ORDER RESERVED */
static const char *const token2string [] = {
@ -70,10 +67,8 @@ void luaX_syntaxerror (LexState *ls, const char *s, const char *token) {
void luaX_error (LexState *ls, const char *s, int token) {
char buff[TOKEN_LEN];
luaX_token2str(token, buff);
if (buff[0] == '\0') {
save(ls->L, '\0');
luaX_syntaxerror(ls, s, luaL_buffer(ls->L));
}
if (buff[0] == '\0')
luaX_syntaxerror(ls, s, ls->L->Mbuffer);
else
luaX_syntaxerror(ls, s, buff);
}
@ -96,16 +91,6 @@ static void luaX_invalidchar (LexState *ls, int c) {
}
static const char *readname (lua_State *L, LexState *LS) {
luaL_resetbuffer(L);
do {
save_and_next(L, LS);
} while (isalnum(LS->current) || LS->current == '_');
save(L, '\0');
return L->Mbuffer+L->Mbuffbase;
}
static void inclinenumber (LexState *LS) {
next(LS); /* skip '\n' */
++LS->linenumber;
@ -138,61 +123,133 @@ void luaX_setinput (lua_State *L, LexState *LS, ZIO *z, TString *source) {
*/
/* use Mbuffer to store names, literal strings and numbers */
#define EXTRABUFF 128
#define checkbuffer(L, n, len) if ((len)+(n) > L->Mbuffsize) \
luaO_openspace(L, (len)+(n)+EXTRABUFF)
#define save(L, c, l) (L->Mbuffer[l++] = (char)c)
#define save_and_next(L, LS, l) (save(L, LS->current, l), next(LS))
static const char *readname (LexState *LS) {
lua_State *L = LS->L;
size_t l = 0;
checkbuffer(L, 10, l);
do {
checkbuffer(L, 10, l);
save_and_next(L, LS, l);
} while (isalnum(LS->current) || LS->current == '_');
save(L, '\0', l);
return L->Mbuffer;
}
/* LUA_NUMBER */
static void read_number (LexState *LS, int comma) {
lua_State *L = LS->L;
size_t l = 0;
checkbuffer(L, 10, l);
if (comma) save(L, '.', l);
while (isdigit(LS->current)) {
checkbuffer(L, 10, l);
save_and_next(L, LS, l);
}
if (LS->current == '.') {
save_and_next(L, LS, l);
if (LS->current == '.') {
save_and_next(L, LS, l);
save(L, '\0', l);
luaX_error(LS, "ambiguous syntax"
" (decimal point x string concatenation)", TK_NUMBER);
}
}
while (isdigit(LS->current)) {
checkbuffer(L, 10, l);
save_and_next(L, LS, l);
}
if (LS->current == 'e' || LS->current == 'E') {
save_and_next(L, LS, l); /* read 'E' */
if (LS->current == '+' || LS->current == '-')
save_and_next(L, LS, l); /* optional exponent sign */
while (isdigit(LS->current)) {
checkbuffer(L, 10, l);
save_and_next(L, LS, l);
}
}
save(L, '\0', l);
if (!luaO_str2d(L->Mbuffer, &LS->t.seminfo.r))
luaX_error(LS, "malformed number", TK_NUMBER);
}
static void read_long_string (lua_State *L, LexState *LS) {
static void read_long_string (LexState *LS) {
lua_State *L = LS->L;
int cont = 0;
size_t l = 0;
checkbuffer(L, 10, l);
save(L, '[', l); /* save first '[' */
save_and_next(L, LS, l); /* pass the second '[' */
for (;;) {
checkbuffer(L, 10, l);
switch (LS->current) {
case EOZ:
save(L, '\0', l);
luaX_error(LS, "unfinished long string", TK_STRING);
break; /* to avoid warnings */
case '[':
save_and_next(L, LS);
save_and_next(L, LS, l);
if (LS->current == '[') {
cont++;
save_and_next(L, LS);
save_and_next(L, LS, l);
}
continue;
case ']':
save_and_next(L, LS);
save_and_next(L, LS, l);
if (LS->current == ']') {
if (cont == 0) goto endloop;
cont--;
save_and_next(L, LS);
save_and_next(L, LS, l);
}
continue;
case '\n':
save(L, '\n');
save(L, '\n', l);
inclinenumber(LS);
continue;
default:
save_and_next(L, LS);
save_and_next(L, LS, l);
}
} endloop:
save_and_next(L, LS); /* skip the second ']' */
LS->t.seminfo.ts = luaS_newlstr(L, L->Mbuffer+(L->Mbuffbase+2),
L->Mbuffnext-L->Mbuffbase-4);
save_and_next(L, LS, l); /* skip the second ']' */
save(L, '\0', l);
LS->t.seminfo.ts = luaS_newlstr(L, L->Mbuffer+2, l-5);
}
static void read_string (lua_State *L, LexState *LS, int del) {
save_and_next(L, LS);
static void read_string (LexState *LS, int del) {
lua_State *L = LS->L;
size_t l = 0;
checkbuffer(L, 10, l);
save_and_next(L, LS, l);
while (LS->current != del) {
checkbuffer(L, 10, l);
switch (LS->current) {
case EOZ: case '\n':
save(L, '\0', l);
luaX_error(LS, "unfinished string", TK_STRING);
break; /* to avoid warnings */
case '\\':
next(LS); /* do not save the '\' */
switch (LS->current) {
case 'a': save(L, '\a'); next(LS); break;
case 'b': save(L, '\b'); next(LS); break;
case 'f': save(L, '\f'); next(LS); break;
case 'n': save(L, '\n'); next(LS); break;
case 'r': save(L, '\r'); next(LS); break;
case 't': save(L, '\t'); next(LS); break;
case 'v': save(L, '\v'); next(LS); break;
case '\n': save(L, '\n'); inclinenumber(LS); break;
case 'a': save(L, '\a', l); next(LS); break;
case 'b': save(L, '\b', l); next(LS); break;
case 'f': save(L, '\f', l); next(LS); break;
case 'n': save(L, '\n', l); next(LS); break;
case 'r': save(L, '\r', l); next(LS); break;
case 't': save(L, '\t', l); next(LS); break;
case 'v': save(L, '\v', l); next(LS); break;
case '\n': save(L, '\n', l); inclinenumber(LS); break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9': {
int c = 0;
@ -201,28 +258,28 @@ static void read_string (lua_State *L, LexState *LS, int del) {
c = 10*c + (LS->current-'0');
next(LS);
} while (++i<3 && isdigit(LS->current));
if (c != (unsigned char)c)
if (c != (unsigned char)c) {
save(L, '\0', l);
luaX_error(LS, "escape sequence too large", TK_STRING);
save(L, c);
}
save(L, c, l);
break;
}
default: /* handles \\, \", \', and \? */
save(L, LS->current);
next(LS);
save_and_next(L, LS, l);
}
break;
default:
save_and_next(L, LS);
save_and_next(L, LS, l);
}
}
save_and_next(L, LS); /* skip delimiter */
LS->t.seminfo.ts = luaS_newlstr(L, L->Mbuffer+(L->Mbuffbase+1),
L->Mbuffnext-L->Mbuffbase-2);
save_and_next(L, LS, l); /* skip delimiter */
save(L, '\0', l);
LS->t.seminfo.ts = luaS_newlstr(L, L->Mbuffer+1, l-3);
}
int luaX_lex (LexState *LS) {
lua_State *L = LS->L;
for (;;) {
switch (LS->current) {
@ -245,12 +302,10 @@ int luaX_lex (LexState *LS) {
continue;
case '[':
luaL_resetbuffer(L);
save_and_next(L, LS);
next(LS);
if (LS->current != '[') return '[';
else {
save_and_next(L, LS); /* pass the second '[' */
read_long_string(L, LS);
read_long_string(LS);
return TK_STRING;
}
@ -276,13 +331,11 @@ int luaX_lex (LexState *LS) {
case '"':
case '\'':
luaL_resetbuffer(L);
read_string(L, LS, LS->current);
read_string(LS, LS->current);
return TK_STRING;
case '.':
luaL_resetbuffer(L);
save_and_next(L, LS);
next(LS);
if (LS->current == '.') {
next(LS);
if (LS->current == '.') {
@ -292,35 +345,14 @@ int luaX_lex (LexState *LS) {
else return TK_CONCAT; /* .. */
}
else if (!isdigit(LS->current)) return '.';
else goto fraction; /* LS->current is a digit */
else {
read_number(LS, 1);
return TK_NUMBER;
}
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
luaL_resetbuffer(L);
do {
save_and_next(L, LS);
} while (isdigit(LS->current));
if (LS->current == '.') {
save_and_next(L, LS);
if (LS->current == '.') {
save(L, '.');
luaX_error(LS, "ambiguous syntax"
" (decimal point x string concatenation)", TK_NUMBER);
}
}
fraction: /* LUA_NUMBER */
while (isdigit(LS->current))
save_and_next(L, LS);
if (LS->current == 'e' || LS->current == 'E') {
save_and_next(L, LS); /* read 'E' */
if (LS->current == '+' || LS->current == '-')
save_and_next(L, LS); /* optional exponent sign */
while (isdigit(LS->current))
save_and_next(L, LS);
}
save(L, '\0');
if (!luaO_str2d(L->Mbuffer+L->Mbuffbase, &LS->t.seminfo.r))
luaX_error(LS, "malformed number", TK_NUMBER);
read_number(LS, 0);
return TK_NUMBER;
case EOZ:
@ -337,7 +369,7 @@ int luaX_lex (LexState *LS) {
return c;
}
tname: { /* identifier or reserved word */
TString *ts = luaS_new(L, readname(L, LS));
TString *ts = luaS_new(LS->L, readname(LS));
if (ts->marked >= RESERVEDMARK) /* reserved word? */
return ts->marked-RESERVEDMARK+FIRST_RESERVED;
LS->t.seminfo.ts = ts;

13
lobject.c

@ -1,5 +1,5 @@
/*
** $Id: lobject.c,v 1.44 2000/08/09 19:16:57 roberto Exp roberto $
** $Id: lobject.c,v 1.45 2000/08/11 16:17:28 roberto Exp roberto $
** Some generic functions over Lua objects
** See Copyright Notice in lua.h
*/
@ -9,7 +9,9 @@
#include "lua.h"
#include "lmem.h"
#include "lobject.h"
#include "lstate.h"
/*
@ -53,6 +55,15 @@ int luaO_equalObj (const TObject *t1, const TObject *t2) {
}
char *luaO_openspace (lua_State *L, size_t n) {
if (n > L->Mbuffsize) {
luaM_reallocvector(L, L->Mbuffer, n, char);
L->Mbuffsize = n;
}
return L->Mbuffer;
}
static double expten (unsigned int e) {
double exp = 10.0;
double res = 1.0;

3
lobject.h

@ -1,5 +1,5 @@
/*
** $Id: lobject.h,v 1.73 2000/08/21 14:34:43 roberto Exp roberto $
** $Id: lobject.h,v 1.74 2000/08/22 17:44:17 roberto Exp roberto $
** Type definitions for Lua objects
** See Copyright Notice in lua.h
*/
@ -193,6 +193,7 @@ extern const TObject luaO_nilobject;
#define luaO_typename(o) luaO_typenames[ttype(o)]
lint32 luaO_power2 (lint32 n);
char *luaO_openspace (lua_State *L, size_t n);
int luaO_equalObj (const TObject *t1, const TObject *t2);
int luaO_str2d (const char *s, Number *result);

4
lstate.c

@ -1,5 +1,5 @@
/*
** $Id: lstate.c,v 1.35 2000/08/31 13:30:39 roberto Exp roberto $
** $Id: lstate.c,v 1.36 2000/09/05 19:33:32 roberto Exp roberto $
** Global State
** See Copyright Notice in lua.h
*/
@ -35,9 +35,7 @@ lua_State *lua_newstate (int stacksize) {
L->strt.hash = NULL;
L->udt.hash = NULL;
L->Mbuffer = NULL;
L->Mbuffbase = 0;
L->Mbuffsize = 0;
L->Mbuffnext = 0;
L->rootproto = NULL;
L->rootcl = NULL;
L->roottable = NULL;

4
lstate.h

@ -1,5 +1,5 @@
/*
** $Id: lstate.h,v 1.36 2000/08/08 20:42:07 roberto Exp roberto $
** $Id: lstate.h,v 1.37 2000/08/28 17:57:04 roberto Exp roberto $
** Global State
** See Copyright Notice in lua.h
*/
@ -61,9 +61,7 @@ struct lua_State {
StkId Cbase; /* base for current C function */
struct lua_longjmp *errorJmp; /* current error recover point */
char *Mbuffer; /* global buffer */
size_t Mbuffbase; /* current first position of Mbuffer */
size_t Mbuffsize; /* size of Mbuffer */
size_t Mbuffnext; /* next position to fill in Mbuffer */
/* global state */
Proto *rootproto; /* list of all prototypes */
Closure *rootcl; /* list of all closures */

114
lstrlib.c

@ -1,5 +1,5 @@
/*
** $Id: lstrlib.c,v 1.50 2000/08/31 20:23:40 roberto Exp roberto $
** $Id: lstrlib.c,v 1.51 2000/09/05 19:33:32 roberto Exp $
** Standard library for string operations and pattern-matching
** See Copyright Notice in lua.h
*/
@ -18,13 +18,6 @@
static void addnchar (lua_State *L, const char *s, size_t n) {
char *b = luaL_openspace(L, n);
memcpy(b, s, n);
luaL_addsize(L, n);
}
static int str_len (lua_State *L) {
size_t l;
luaL_check_lstr(L, 1, &l);
@ -33,11 +26,6 @@ static int str_len (lua_State *L) {
}
static void closeandpush (lua_State *L) {
lua_pushlstring(L, luaL_buffer(L), luaL_getsize(L));
}
static long posrelat (long pos, size_t len) {
/* relative string position: negative means back from end */
return (pos>=0) ? pos : (long)len+pos+1;
@ -61,11 +49,12 @@ static int str_sub (lua_State *L) {
static int str_lower (lua_State *L) {
size_t l;
size_t i;
luaL_Buffer b;
const char *s = luaL_check_lstr(L, 1, &l);
luaL_resetbuffer(L);
luaL_buffinit(L, &b);
for (i=0; i<l; i++)
luaL_addchar(L, tolower((unsigned char)(s[i])));
closeandpush(L);
luaL_putchar(&b, tolower((unsigned char)(s[i])));
luaL_pushresult(&b);
return 1;
}
@ -73,22 +62,24 @@ static int str_lower (lua_State *L) {
static int str_upper (lua_State *L) {
size_t l;
size_t i;
luaL_Buffer b;
const char *s = luaL_check_lstr(L, 1, &l);
luaL_resetbuffer(L);
luaL_buffinit(L, &b);
for (i=0; i<l; i++)
luaL_addchar(L, toupper((unsigned char)(s[i])));
closeandpush(L);
luaL_putchar(&b, toupper((unsigned char)(s[i])));
luaL_pushresult(&b);
return 1;
}
static int str_rep (lua_State *L) {
size_t l;
luaL_Buffer b;
const char *s = luaL_check_lstr(L, 1, &l);
int n = luaL_check_int(L, 2);
luaL_resetbuffer(L);
luaL_buffinit(L, &b);
while (n-- > 0)
addnchar(L, s, l);
closeandpush(L);
luaL_addlstring(&b, s, l);
luaL_pushresult(&b);
return 1;
}
@ -106,13 +97,14 @@ static int str_byte (lua_State *L) {
static int str_char (lua_State *L) {
int n = lua_gettop(L); /* number of arguments */
int i;
luaL_resetbuffer(L);
luaL_Buffer b;
luaL_buffinit(L, &b);
for (i=1; i<=n; i++) {
int c = luaL_check_int(L, i);
luaL_arg_check(L, (unsigned char)c == c, i, "invalid value");
luaL_addchar(L, (unsigned char)c);
luaL_putchar(&b, (unsigned char)c);
}
closeandpush(L);
luaL_pushresult(&b);
return 1;
}
@ -445,43 +437,37 @@ static int str_find (lua_State *L) {
}
static void add_s (lua_State *L, struct Capture *cap) {
static void add_s (lua_State *L, luaL_Buffer *b, struct Capture *cap) {
if (lua_isstring(L, 3)) {
const char *news = lua_tostring(L, 3);
size_t l = lua_strlen(L, 3);
size_t i;
for (i=0; i<l; i++) {
if (news[i] != ESC)
luaL_addchar(L, news[i]);
luaL_putchar(b, news[i]);
else {
i++; /* skip ESC */
if (!isdigit((unsigned char)news[i]))
luaL_addchar(L, news[i]);
luaL_putchar(b, news[i]);
else {
int level = check_capture(L, news[i], cap);
addnchar(L, cap->capture[level].init, cap->capture[level].len);
luaL_addlstring(b, cap->capture[level].init, cap->capture[level].len);
}
}
}
}
else { /* is a function */
int status;
size_t oldbuff;
int n;
const char *s;
lua_pushvalue(L, 3);
n = push_captures(L, cap);
/* function may use buffer, so save it and create a new one */
oldbuff = luaL_newbuffer(L, 0);
status = lua_call(L, n, 1);
/* restore old buffer */
luaL_oldbuffer(L, oldbuff);
if (status != 0)
lua_error(L, NULL);
s = lua_tostring(L, -1);
if (s)
addnchar(L, lua_tostring(L, -1), lua_strlen(L, -1));
lua_pop(L, 1); /* pop function result */
lua_error(L, NULL); /* propagate error */
if (lua_isstring(L, -1))
luaL_addvalue(b); /* add return to accumulated result */
else
lua_pop(L, 1); /* function result is not a string: pop it */
}
}
@ -494,10 +480,11 @@ static int str_gsub (lua_State *L) {
int anchor = (*p == '^') ? (p++, 1) : 0;
int n = 0;
struct Capture cap;
luaL_Buffer b;
luaL_arg_check(L,
lua_gettop(L) >= 3 && (lua_isstring(L, 3) || lua_isfunction(L, 3)),
3, "string or function expected");
luaL_resetbuffer(L);
luaL_buffinit(L, &b);
cap.src_end = src+srcl;
while (n < max_s) {
const char *e;
@ -505,17 +492,17 @@ static int str_gsub (lua_State *L) {
e = match(L, src, p, &cap);
if (e) {
n++;
add_s(L, &cap);
add_s(L, &b, &cap);
}
if (e && e>src) /* non empty match? */
src = e; /* skip it */
else if (src < cap.src_end)
luaL_addchar(L, *src++);
luaL_putchar(&b, *src++);
else break;
if (anchor) break;
}
addnchar(L, src, cap.src_end-src);
closeandpush(L);
luaL_addlstring(&b, src, cap.src_end-src);
luaL_pushresult(&b);
lua_pushnumber(L, n); /* number of substitutions */
return 2;
}
@ -523,40 +510,43 @@ static int str_gsub (lua_State *L) {
/* }====================================================== */
static void luaI_addquoted (lua_State *L, int arg) {
static void luaI_addquoted (lua_State *L, luaL_Buffer *b, int arg) {
size_t l;
const char *s = luaL_check_lstr(L, arg, &l);
luaL_addchar(L, '"');
luaL_putchar(b, '"');
while (l--) {
switch (*s) {
case '"': case '\\': case '\n':
luaL_addchar(L, '\\');
luaL_addchar(L, *s);
luaL_putchar(b, '\\');
luaL_putchar(b, *s);
break;
case '\0': addnchar(L, "\\000", 4); break;
default: luaL_addchar(L, *s);
case '\0': luaL_addlstring(b, "\\000", 4); break;
default: luaL_putchar(b, *s);
}
s++;
}
luaL_addchar(L, '"');
luaL_putchar(b, '"');
}
/* maximum size of each formated item (> len(format('%99.99f', -1e308))) */
#define MAX_ITEM 512
/* maximum size of each format specification (such as '%-099.99d') */
#define MAX_FORMAT 20 /* arbitrary limit */
#define MAX_FORMAT 20
static int str_format (lua_State *L) {
int arg = 1;
const char *strfrmt = luaL_check_string(L, arg);
luaL_resetbuffer(L);
luaL_Buffer b;
luaL_buffinit(L, &b);
while (*strfrmt) {
if (*strfrmt != '%')
luaL_addchar(L, *strfrmt++);
luaL_putchar(&b, *strfrmt++);
else if (*++strfrmt == '%')
luaL_addchar(L, *strfrmt++); /* %% */
luaL_putchar(&b, *strfrmt++); /* %% */
else { /* format item */
struct Capture cap;
char form[MAX_FORMAT]; /* to store the format ('%...') */
char *buff; /* to store the formatted item */
char buff[MAX_ITEM]; /* to store the formatted item */
const char *initf = strfrmt;
form[0] = '%';
if (isdigit((unsigned char)*initf) && *(initf+1) == '$') {
@ -572,7 +562,6 @@ static int str_format (lua_State *L) {
lua_error(L, "invalid format (width or precision too long)");
strncpy(form+1, initf, strfrmt-initf+1); /* +1 to include conversion */
form[strfrmt-initf+2] = 0;
buff = luaL_openspace(L, 512); /* 512 > len(format('%99.99f', -1e308)) */
switch (*strfrmt++) {
case 'c': case 'd': case 'i':
sprintf(buff, form, luaL_check_int(L, arg));
@ -584,7 +573,7 @@ static int str_format (lua_State *L) {
sprintf(buff, form, luaL_check_number(L, arg));
break;
case 'q':
luaI_addquoted(L, arg);
luaI_addquoted(L, &b, arg);
continue; /* skip the "addsize" at the end */
case 's': {
size_t l;
@ -592,7 +581,8 @@ static int str_format (lua_State *L) {
if (cap.capture[1].len == 0 && l >= 100) {
/* no precision and string is too long to be formatted;
keep original string */
addnchar(L, s, l);
lua_pushvalue(L, arg);
luaL_addvalue(&b);
continue; /* skip the "addsize" at the end */
}
else {
@ -603,10 +593,10 @@ static int str_format (lua_State *L) {
default: /* also treat cases 'pnLlh' */
lua_error(L, "invalid option in `format'");
}
luaL_addsize(L, strlen(buff));
luaL_addlstring(&b, buff, strlen(buff));
}
}
closeandpush(L); /* push the result */
luaL_pushresult(&b);
return 1;
}

4
lundump.c

@ -1,5 +1,5 @@
/*
** $Id: lundump.c,v 1.29 2000/06/28 14:12:55 lhf Exp lhf $
** $Id: lundump.c,v 1.27 2000/09/04 18:53:41 roberto Exp roberto $
** load bytecodes from files
** See Copyright Notice in lua.h
*/
@ -86,7 +86,7 @@ static TString* LoadString (lua_State* L, ZIO* Z, int swap)
return NULL;
else
{
char* s=luaL_openspace(L,size);
char* s=luaO_openspace(L,size);
LoadBlock(L,s,size,Z);
return luaS_newlstr(L,s,size-1); /* remove trailing '\0' */
}

5
lvm.c

@ -1,5 +1,5 @@
/*
** $Id: lvm.c,v 1.133 2000/08/31 21:02:55 roberto Exp roberto $
** $Id: lvm.c,v 1.134 2000/09/05 19:33:32 roberto Exp roberto $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
@ -12,7 +12,6 @@
#include "lua.h"
#include "lapi.h"
#include "lauxlib.h"
#include "ldebug.h"
#include "ldo.h"
#include "lfunc.h"
@ -300,7 +299,7 @@ void luaV_strconc (lua_State *L, int total, StkId top) {
n++;
}
if (tl > MAX_SIZET) lua_error(L, "string size overflow");
buffer = luaL_openspace(L, tl);
buffer = luaO_openspace(L, tl);
tl = 0;
for (i=n; i>0; i--) { /* concat all strings */
size_t l = tsvalue(top-i)->u.s.len;

Loading…
Cancel
Save