new scheme for buffers
This commit is contained in:
97
lauxlib.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
|
** Auxiliary functions for building Lua libraries
|
||||||
** See Copyright Notice in lua.h
|
** 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
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
|
** Auxiliary functions for building Lua libraries
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "lua.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, ...);
|
void luaL_verror (lua_State *L, const char *fmt, ...);
|
||||||
int luaL_findstring (const char *name, const char *const list[]);
|
int luaL_findstring (const char *name, const char *const list[]);
|
||||||
void luaL_chunkid (char *out, const char *source, int len);
|
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])))
|
#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
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
5
ldo.c
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
|
** Stack and Call structure of Lua
|
||||||
** See Copyright Notice in lua.h
|
** 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 */
|
int c; /* look ahead char */
|
||||||
FILE *f = (filename == NULL) ? stdin : fopen(filename, "r");
|
FILE *f = (filename == NULL) ? stdin : fopen(filename, "r");
|
||||||
if (f == NULL) return LUA_ERRFILE; /* unable to open file */
|
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);
|
c = fgetc(f);
|
||||||
ungetc(c, f);
|
ungetc(c, f);
|
||||||
bin = (c == ID_CHUNK);
|
bin = (c == ID_CHUNK);
|
||||||
|
|||||||
8
lgc.c
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
|
** Garbage Collector
|
||||||
** See Copyright Notice in lua.h
|
** 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) {
|
long lua_collectgarbage (lua_State *L, long limit) {
|
||||||
unsigned long recovered = L->nblocks; /* to subtract `nblocks' after gc */
|
unsigned long recovered = L->nblocks; /* to subtract `nblocks' after gc */
|
||||||
markall(L);
|
markall(L);
|
||||||
@@ -340,8 +342,8 @@ long lua_collectgarbage (lua_State *L, long limit) {
|
|||||||
luaC_collect(L, 0);
|
luaC_collect(L, 0);
|
||||||
recovered = recovered - L->nblocks;
|
recovered = recovered - L->nblocks;
|
||||||
L->GCthreshold = (limit == 0) ? 2*L->nblocks : L->nblocks+limit;
|
L->GCthreshold = (limit == 0) ? 2*L->nblocks : L->nblocks+limit;
|
||||||
if (L->Mbuffsize > L->Mbuffnext*4) { /* is buffer too big? */
|
if (L->Mbuffsize > MINBUFFER*2) { /* is buffer too big? */
|
||||||
L->Mbuffsize /= 2; /* still larger than Mbuffnext*2 */
|
L->Mbuffsize /= 2; /* still larger than MINBUFFER */
|
||||||
luaM_reallocvector(L, L->Mbuffer, L->Mbuffsize, char);
|
luaM_reallocvector(L, L->Mbuffer, L->Mbuffsize, char);
|
||||||
}
|
}
|
||||||
callgcTM(L, &luaO_nilobject);
|
callgcTM(L, &luaO_nilobject);
|
||||||
|
|||||||
87
liolib.c
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
|
** Standard I/O (and system) library
|
||||||
** See Copyright Notice in lua.h
|
** 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);
|
if (c == NEED_OTHER) c = getc(f);
|
||||||
m = (c==EOF) ? 0 : luaI_singlematch(c, p, ep);
|
m = (c==EOF) ? 0 : luaI_singlematch(c, p, ep);
|
||||||
if (m) {
|
if (m) {
|
||||||
if (!inskip) luaL_addchar(L, c);
|
if (!inskip) luaL_putchar(L, c);
|
||||||
c = NEED_OTHER;
|
c = NEED_OTHER;
|
||||||
}
|
}
|
||||||
switch (*ep) {
|
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 */
|
while (m) { /* reads the same item until it fails */
|
||||||
c = getc(f);
|
c = getc(f);
|
||||||
m = (c==EOF) ? 0 : luaI_singlematch(c, p, ep);
|
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 */
|
/* go through to continue reading the pattern */
|
||||||
case '?': /* optional */
|
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;
|
int c;
|
||||||
|
luaL_Buffer b;
|
||||||
|
luaL_buffinit(L, &b);
|
||||||
do { c = fgetc(f); } while (isspace(c)); /* skip spaces */
|
do { c = fgetc(f); } while (isspace(c)); /* skip spaces */
|
||||||
while (c != EOF && !isspace(c)) {
|
while (c != EOF && !isspace(c)) {
|
||||||
luaL_addchar(L, c);
|
luaL_putchar(&b, c);
|
||||||
c = fgetc(f);
|
c = fgetc(f);
|
||||||
}
|
}
|
||||||
ungetc(c, 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) {
|
static int read_line (lua_State *L, FILE *f) {
|
||||||
int n;
|
int n = 0;
|
||||||
char *b;
|
luaL_Buffer b;
|
||||||
|
luaL_buffinit(L, &b);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
b = luaL_openspace(L, HUNK_LINE);
|
char *p = luaL_prepbuffer(&b);
|
||||||
if (!fgets(b, HUNK_LINE, f)) return 0; /* read fails */
|
if (!fgets(p, LUAL_BUFFERSIZE, f)) /* read fails? */
|
||||||
n = strlen(b);
|
break;
|
||||||
if (b[n-1] != '\n')
|
n = strlen(p);
|
||||||
luaL_addsize(L, n);
|
if (p[n-1] != '\n')
|
||||||
|
luaL_addsize(&b, n);
|
||||||
else {
|
else {
|
||||||
luaL_addsize(L, n-1); /* do not add the `\n' */
|
luaL_addsize(&b, n-1); /* do not add the `\n' */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 1;
|
luaL_pushresult(&b); /* close buffer */
|
||||||
|
return (n > 0); /* read something? */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void read_file (lua_State *L, FILE *f) {
|
static void read_file (lua_State *L, FILE *f) {
|
||||||
size_t n;
|
size_t len = 0;
|
||||||
do {
|
size_t size = BUFSIZ;
|
||||||
char *b = luaL_openspace(L, HUNK_FILE);
|
char *buffer = NULL;
|
||||||
n = fread(b, sizeof(char), HUNK_FILE, f);
|
for (;;) {
|
||||||
luaL_addsize(L, n);
|
buffer = (char *)realloc(buffer, size);
|
||||||
} while (n==HUNK_FILE);
|
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) {
|
static int read_chars (lua_State *L, FILE *f, size_t n) {
|
||||||
char *b = luaL_openspace(L, n);
|
char *buffer;
|
||||||
size_t n1 = fread(b, sizeof(char), n, f);
|
size_t n1;
|
||||||
luaL_addsize(L, n1);
|
char statbuff[BUFSIZ];
|
||||||
return (n == n1);
|
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
|
else
|
||||||
luaL_checkstack(L, lastarg-firstarg+1, "too many arguments");
|
luaL_checkstack(L, lastarg-firstarg+1, "too many arguments");
|
||||||
for (n = firstarg; n<=lastarg; n++) {
|
for (n = firstarg; n<=lastarg; n++) {
|
||||||
size_t l;
|
|
||||||
int success;
|
int success;
|
||||||
luaL_resetbuffer(L);
|
|
||||||
if (lua_isnumber(L, n))
|
if (lua_isnumber(L, n))
|
||||||
success = read_chars(L, f, (size_t)lua_tonumber(L, n));
|
success = read_chars(L, f, (size_t)lua_tonumber(L, n));
|
||||||
else {
|
else {
|
||||||
@@ -397,8 +416,7 @@ static int io_read (lua_State *L) {
|
|||||||
success = 1; /* always success */
|
success = 1; /* always success */
|
||||||
break;
|
break;
|
||||||
case 'w': /* word */
|
case 'w': /* word */
|
||||||
read_word(L, f);
|
success = read_word(L, f);
|
||||||
success = 0; /* must read something to succeed */
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
luaL_argerror(L, n, "invalid format");
|
luaL_argerror(L, n, "invalid format");
|
||||||
@@ -406,9 +424,10 @@ static int io_read (lua_State *L) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
l = luaL_getsize(L);
|
if (!success) {
|
||||||
if (!success && l==0) break; /* read fails */
|
lua_pop(L, 1); /* remove last result */
|
||||||
lua_pushlstring(L, luaL_buffer(L), l);
|
break; /* read fails */
|
||||||
|
}
|
||||||
} endloop:
|
} endloop:
|
||||||
return n - firstarg;
|
return n - firstarg;
|
||||||
}
|
}
|
||||||
|
|||||||
196
llex.c
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
|
** Lexical Analyzer
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -27,9 +27,6 @@
|
|||||||
#define next(LS) (LS->current = zgetc(LS->z))
|
#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 */
|
/* ORDER RESERVED */
|
||||||
static const char *const token2string [] = {
|
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) {
|
void luaX_error (LexState *ls, const char *s, int token) {
|
||||||
char buff[TOKEN_LEN];
|
char buff[TOKEN_LEN];
|
||||||
luaX_token2str(token, buff);
|
luaX_token2str(token, buff);
|
||||||
if (buff[0] == '\0') {
|
if (buff[0] == '\0')
|
||||||
save(ls->L, '\0');
|
luaX_syntaxerror(ls, s, ls->L->Mbuffer);
|
||||||
luaX_syntaxerror(ls, s, luaL_buffer(ls->L));
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
luaX_syntaxerror(ls, s, buff);
|
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) {
|
static void inclinenumber (LexState *LS) {
|
||||||
next(LS); /* skip '\n' */
|
next(LS); /* skip '\n' */
|
||||||
++LS->linenumber;
|
++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 */
|
||||||
|
|
||||||
static void read_long_string (lua_State *L, LexState *LS) {
|
#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 (LexState *LS) {
|
||||||
|
lua_State *L = LS->L;
|
||||||
int cont = 0;
|
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 (;;) {
|
for (;;) {
|
||||||
|
checkbuffer(L, 10, l);
|
||||||
switch (LS->current) {
|
switch (LS->current) {
|
||||||
case EOZ:
|
case EOZ:
|
||||||
|
save(L, '\0', l);
|
||||||
luaX_error(LS, "unfinished long string", TK_STRING);
|
luaX_error(LS, "unfinished long string", TK_STRING);
|
||||||
break; /* to avoid warnings */
|
break; /* to avoid warnings */
|
||||||
case '[':
|
case '[':
|
||||||
save_and_next(L, LS);
|
save_and_next(L, LS, l);
|
||||||
if (LS->current == '[') {
|
if (LS->current == '[') {
|
||||||
cont++;
|
cont++;
|
||||||
save_and_next(L, LS);
|
save_and_next(L, LS, l);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
case ']':
|
case ']':
|
||||||
save_and_next(L, LS);
|
save_and_next(L, LS, l);
|
||||||
if (LS->current == ']') {
|
if (LS->current == ']') {
|
||||||
if (cont == 0) goto endloop;
|
if (cont == 0) goto endloop;
|
||||||
cont--;
|
cont--;
|
||||||
save_and_next(L, LS);
|
save_and_next(L, LS, l);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
case '\n':
|
case '\n':
|
||||||
save(L, '\n');
|
save(L, '\n', l);
|
||||||
inclinenumber(LS);
|
inclinenumber(LS);
|
||||||
continue;
|
continue;
|
||||||
default:
|
default:
|
||||||
save_and_next(L, LS);
|
save_and_next(L, LS, l);
|
||||||
}
|
}
|
||||||
} endloop:
|
} endloop:
|
||||||
save_and_next(L, LS); /* skip the second ']' */
|
save_and_next(L, LS, l); /* skip the second ']' */
|
||||||
LS->t.seminfo.ts = luaS_newlstr(L, L->Mbuffer+(L->Mbuffbase+2),
|
save(L, '\0', l);
|
||||||
L->Mbuffnext-L->Mbuffbase-4);
|
LS->t.seminfo.ts = luaS_newlstr(L, L->Mbuffer+2, l-5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void read_string (lua_State *L, LexState *LS, int del) {
|
static void read_string (LexState *LS, int del) {
|
||||||
save_and_next(L, LS);
|
lua_State *L = LS->L;
|
||||||
|
size_t l = 0;
|
||||||
|
checkbuffer(L, 10, l);
|
||||||
|
save_and_next(L, LS, l);
|
||||||
while (LS->current != del) {
|
while (LS->current != del) {
|
||||||
|
checkbuffer(L, 10, l);
|
||||||
switch (LS->current) {
|
switch (LS->current) {
|
||||||
case EOZ: case '\n':
|
case EOZ: case '\n':
|
||||||
|
save(L, '\0', l);
|
||||||
luaX_error(LS, "unfinished string", TK_STRING);
|
luaX_error(LS, "unfinished string", TK_STRING);
|
||||||
break; /* to avoid warnings */
|
break; /* to avoid warnings */
|
||||||
case '\\':
|
case '\\':
|
||||||
next(LS); /* do not save the '\' */
|
next(LS); /* do not save the '\' */
|
||||||
switch (LS->current) {
|
switch (LS->current) {
|
||||||
case 'a': save(L, '\a'); next(LS); break;
|
case 'a': save(L, '\a', l); next(LS); break;
|
||||||
case 'b': save(L, '\b'); next(LS); break;
|
case 'b': save(L, '\b', l); next(LS); break;
|
||||||
case 'f': save(L, '\f'); next(LS); break;
|
case 'f': save(L, '\f', l); next(LS); break;
|
||||||
case 'n': save(L, '\n'); next(LS); break;
|
case 'n': save(L, '\n', l); next(LS); break;
|
||||||
case 'r': save(L, '\r'); next(LS); break;
|
case 'r': save(L, '\r', l); next(LS); break;
|
||||||
case 't': save(L, '\t'); next(LS); break;
|
case 't': save(L, '\t', l); next(LS); break;
|
||||||
case 'v': save(L, '\v'); next(LS); break;
|
case 'v': save(L, '\v', l); next(LS); break;
|
||||||
case '\n': save(L, '\n'); inclinenumber(LS); break;
|
case '\n': save(L, '\n', l); inclinenumber(LS); break;
|
||||||
case '0': case '1': case '2': case '3': case '4':
|
case '0': case '1': case '2': case '3': case '4':
|
||||||
case '5': case '6': case '7': case '8': case '9': {
|
case '5': case '6': case '7': case '8': case '9': {
|
||||||
int c = 0;
|
int c = 0;
|
||||||
@@ -201,28 +258,28 @@ static void read_string (lua_State *L, LexState *LS, int del) {
|
|||||||
c = 10*c + (LS->current-'0');
|
c = 10*c + (LS->current-'0');
|
||||||
next(LS);
|
next(LS);
|
||||||
} while (++i<3 && isdigit(LS->current));
|
} 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);
|
luaX_error(LS, "escape sequence too large", TK_STRING);
|
||||||
save(L, c);
|
}
|
||||||
|
save(L, c, l);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: /* handles \\, \", \', and \? */
|
default: /* handles \\, \", \', and \? */
|
||||||
save(L, LS->current);
|
save_and_next(L, LS, l);
|
||||||
next(LS);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
save_and_next(L, LS);
|
save_and_next(L, LS, l);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
save_and_next(L, LS); /* skip delimiter */
|
save_and_next(L, LS, l); /* skip delimiter */
|
||||||
LS->t.seminfo.ts = luaS_newlstr(L, L->Mbuffer+(L->Mbuffbase+1),
|
save(L, '\0', l);
|
||||||
L->Mbuffnext-L->Mbuffbase-2);
|
LS->t.seminfo.ts = luaS_newlstr(L, L->Mbuffer+1, l-3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int luaX_lex (LexState *LS) {
|
int luaX_lex (LexState *LS) {
|
||||||
lua_State *L = LS->L;
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
switch (LS->current) {
|
switch (LS->current) {
|
||||||
|
|
||||||
@@ -245,12 +302,10 @@ int luaX_lex (LexState *LS) {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
case '[':
|
case '[':
|
||||||
luaL_resetbuffer(L);
|
next(LS);
|
||||||
save_and_next(L, LS);
|
|
||||||
if (LS->current != '[') return '[';
|
if (LS->current != '[') return '[';
|
||||||
else {
|
else {
|
||||||
save_and_next(L, LS); /* pass the second '[' */
|
read_long_string(LS);
|
||||||
read_long_string(L, LS);
|
|
||||||
return TK_STRING;
|
return TK_STRING;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -276,13 +331,11 @@ int luaX_lex (LexState *LS) {
|
|||||||
|
|
||||||
case '"':
|
case '"':
|
||||||
case '\'':
|
case '\'':
|
||||||
luaL_resetbuffer(L);
|
read_string(LS, LS->current);
|
||||||
read_string(L, LS, LS->current);
|
|
||||||
return TK_STRING;
|
return TK_STRING;
|
||||||
|
|
||||||
case '.':
|
case '.':
|
||||||
luaL_resetbuffer(L);
|
next(LS);
|
||||||
save_and_next(L, LS);
|
|
||||||
if (LS->current == '.') {
|
if (LS->current == '.') {
|
||||||
next(LS);
|
next(LS);
|
||||||
if (LS->current == '.') {
|
if (LS->current == '.') {
|
||||||
@@ -292,35 +345,14 @@ int luaX_lex (LexState *LS) {
|
|||||||
else return TK_CONCAT; /* .. */
|
else return TK_CONCAT; /* .. */
|
||||||
}
|
}
|
||||||
else if (!isdigit(LS->current)) return '.';
|
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 '0': case '1': case '2': case '3': case '4':
|
||||||
case '5': case '6': case '7': case '8': case '9':
|
case '5': case '6': case '7': case '8': case '9':
|
||||||
luaL_resetbuffer(L);
|
read_number(LS, 0);
|
||||||
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);
|
|
||||||
return TK_NUMBER;
|
return TK_NUMBER;
|
||||||
|
|
||||||
case EOZ:
|
case EOZ:
|
||||||
@@ -337,7 +369,7 @@ int luaX_lex (LexState *LS) {
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
tname: { /* identifier or reserved word */
|
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? */
|
if (ts->marked >= RESERVEDMARK) /* reserved word? */
|
||||||
return ts->marked-RESERVEDMARK+FIRST_RESERVED;
|
return ts->marked-RESERVEDMARK+FIRST_RESERVED;
|
||||||
LS->t.seminfo.ts = ts;
|
LS->t.seminfo.ts = ts;
|
||||||
|
|||||||
13
lobject.c
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
|
** Some generic functions over Lua objects
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -9,7 +9,9 @@
|
|||||||
|
|
||||||
#include "lua.h"
|
#include "lua.h"
|
||||||
|
|
||||||
|
#include "lmem.h"
|
||||||
#include "lobject.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) {
|
static double expten (unsigned int e) {
|
||||||
double exp = 10.0;
|
double exp = 10.0;
|
||||||
double res = 1.0;
|
double res = 1.0;
|
||||||
|
|||||||
@@ -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
|
** Type definitions for Lua objects
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -193,6 +193,7 @@ extern const TObject luaO_nilobject;
|
|||||||
#define luaO_typename(o) luaO_typenames[ttype(o)]
|
#define luaO_typename(o) luaO_typenames[ttype(o)]
|
||||||
|
|
||||||
lint32 luaO_power2 (lint32 n);
|
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_equalObj (const TObject *t1, const TObject *t2);
|
||||||
int luaO_str2d (const char *s, Number *result);
|
int luaO_str2d (const char *s, Number *result);
|
||||||
|
|||||||
4
lstate.c
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
|
** Global State
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -35,9 +35,7 @@ lua_State *lua_newstate (int stacksize) {
|
|||||||
L->strt.hash = NULL;
|
L->strt.hash = NULL;
|
||||||
L->udt.hash = NULL;
|
L->udt.hash = NULL;
|
||||||
L->Mbuffer = NULL;
|
L->Mbuffer = NULL;
|
||||||
L->Mbuffbase = 0;
|
|
||||||
L->Mbuffsize = 0;
|
L->Mbuffsize = 0;
|
||||||
L->Mbuffnext = 0;
|
|
||||||
L->rootproto = NULL;
|
L->rootproto = NULL;
|
||||||
L->rootcl = NULL;
|
L->rootcl = NULL;
|
||||||
L->roottable = NULL;
|
L->roottable = NULL;
|
||||||
|
|||||||
4
lstate.h
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
|
** Global State
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -61,9 +61,7 @@ struct lua_State {
|
|||||||
StkId Cbase; /* base for current C function */
|
StkId Cbase; /* base for current C function */
|
||||||
struct lua_longjmp *errorJmp; /* current error recover point */
|
struct lua_longjmp *errorJmp; /* current error recover point */
|
||||||
char *Mbuffer; /* global buffer */
|
char *Mbuffer; /* global buffer */
|
||||||
size_t Mbuffbase; /* current first position of Mbuffer */
|
|
||||||
size_t Mbuffsize; /* size of Mbuffer */
|
size_t Mbuffsize; /* size of Mbuffer */
|
||||||
size_t Mbuffnext; /* next position to fill in Mbuffer */
|
|
||||||
/* global state */
|
/* global state */
|
||||||
Proto *rootproto; /* list of all prototypes */
|
Proto *rootproto; /* list of all prototypes */
|
||||||
Closure *rootcl; /* list of all closures */
|
Closure *rootcl; /* list of all closures */
|
||||||
|
|||||||
114
lstrlib.c
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
|
** Standard library for string operations and pattern-matching
|
||||||
** See Copyright Notice in lua.h
|
** 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) {
|
static int str_len (lua_State *L) {
|
||||||
size_t l;
|
size_t l;
|
||||||
luaL_check_lstr(L, 1, &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) {
|
static long posrelat (long pos, size_t len) {
|
||||||
/* relative string position: negative means back from end */
|
/* relative string position: negative means back from end */
|
||||||
return (pos>=0) ? pos : (long)len+pos+1;
|
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) {
|
static int str_lower (lua_State *L) {
|
||||||
size_t l;
|
size_t l;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
luaL_Buffer b;
|
||||||
const char *s = luaL_check_lstr(L, 1, &l);
|
const char *s = luaL_check_lstr(L, 1, &l);
|
||||||
luaL_resetbuffer(L);
|
luaL_buffinit(L, &b);
|
||||||
for (i=0; i<l; i++)
|
for (i=0; i<l; i++)
|
||||||
luaL_addchar(L, tolower((unsigned char)(s[i])));
|
luaL_putchar(&b, tolower((unsigned char)(s[i])));
|
||||||
closeandpush(L);
|
luaL_pushresult(&b);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,22 +62,24 @@ static int str_lower (lua_State *L) {
|
|||||||
static int str_upper (lua_State *L) {
|
static int str_upper (lua_State *L) {
|
||||||
size_t l;
|
size_t l;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
luaL_Buffer b;
|
||||||
const char *s = luaL_check_lstr(L, 1, &l);
|
const char *s = luaL_check_lstr(L, 1, &l);
|
||||||
luaL_resetbuffer(L);
|
luaL_buffinit(L, &b);
|
||||||
for (i=0; i<l; i++)
|
for (i=0; i<l; i++)
|
||||||
luaL_addchar(L, toupper((unsigned char)(s[i])));
|
luaL_putchar(&b, toupper((unsigned char)(s[i])));
|
||||||
closeandpush(L);
|
luaL_pushresult(&b);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int str_rep (lua_State *L) {
|
static int str_rep (lua_State *L) {
|
||||||
size_t l;
|
size_t l;
|
||||||
|
luaL_Buffer b;
|
||||||
const char *s = luaL_check_lstr(L, 1, &l);
|
const char *s = luaL_check_lstr(L, 1, &l);
|
||||||
int n = luaL_check_int(L, 2);
|
int n = luaL_check_int(L, 2);
|
||||||
luaL_resetbuffer(L);
|
luaL_buffinit(L, &b);
|
||||||
while (n-- > 0)
|
while (n-- > 0)
|
||||||
addnchar(L, s, l);
|
luaL_addlstring(&b, s, l);
|
||||||
closeandpush(L);
|
luaL_pushresult(&b);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,13 +97,14 @@ static int str_byte (lua_State *L) {
|
|||||||
static int str_char (lua_State *L) {
|
static int str_char (lua_State *L) {
|
||||||
int n = lua_gettop(L); /* number of arguments */
|
int n = lua_gettop(L); /* number of arguments */
|
||||||
int i;
|
int i;
|
||||||
luaL_resetbuffer(L);
|
luaL_Buffer b;
|
||||||
|
luaL_buffinit(L, &b);
|
||||||
for (i=1; i<=n; i++) {
|
for (i=1; i<=n; i++) {
|
||||||
int c = luaL_check_int(L, i);
|
int c = luaL_check_int(L, i);
|
||||||
luaL_arg_check(L, (unsigned char)c == c, i, "invalid value");
|
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;
|
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)) {
|
if (lua_isstring(L, 3)) {
|
||||||
const char *news = lua_tostring(L, 3);
|
const char *news = lua_tostring(L, 3);
|
||||||
size_t l = lua_strlen(L, 3);
|
size_t l = lua_strlen(L, 3);
|
||||||
size_t i;
|
size_t i;
|
||||||
for (i=0; i<l; i++) {
|
for (i=0; i<l; i++) {
|
||||||
if (news[i] != ESC)
|
if (news[i] != ESC)
|
||||||
luaL_addchar(L, news[i]);
|
luaL_putchar(b, news[i]);
|
||||||
else {
|
else {
|
||||||
i++; /* skip ESC */
|
i++; /* skip ESC */
|
||||||
if (!isdigit((unsigned char)news[i]))
|
if (!isdigit((unsigned char)news[i]))
|
||||||
luaL_addchar(L, news[i]);
|
luaL_putchar(b, news[i]);
|
||||||
else {
|
else {
|
||||||
int level = check_capture(L, news[i], cap);
|
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 */
|
else { /* is a function */
|
||||||
int status;
|
int status;
|
||||||
size_t oldbuff;
|
|
||||||
int n;
|
int n;
|
||||||
const char *s;
|
|
||||||
lua_pushvalue(L, 3);
|
lua_pushvalue(L, 3);
|
||||||
n = push_captures(L, cap);
|
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);
|
status = lua_call(L, n, 1);
|
||||||
/* restore old buffer */
|
|
||||||
luaL_oldbuffer(L, oldbuff);
|
|
||||||
if (status != 0)
|
if (status != 0)
|
||||||
lua_error(L, NULL);
|
lua_error(L, NULL); /* propagate error */
|
||||||
s = lua_tostring(L, -1);
|
if (lua_isstring(L, -1))
|
||||||
if (s)
|
luaL_addvalue(b); /* add return to accumulated result */
|
||||||
addnchar(L, lua_tostring(L, -1), lua_strlen(L, -1));
|
else
|
||||||
lua_pop(L, 1); /* pop function result */
|
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 anchor = (*p == '^') ? (p++, 1) : 0;
|
||||||
int n = 0;
|
int n = 0;
|
||||||
struct Capture cap;
|
struct Capture cap;
|
||||||
|
luaL_Buffer b;
|
||||||
luaL_arg_check(L,
|
luaL_arg_check(L,
|
||||||
lua_gettop(L) >= 3 && (lua_isstring(L, 3) || lua_isfunction(L, 3)),
|
lua_gettop(L) >= 3 && (lua_isstring(L, 3) || lua_isfunction(L, 3)),
|
||||||
3, "string or function expected");
|
3, "string or function expected");
|
||||||
luaL_resetbuffer(L);
|
luaL_buffinit(L, &b);
|
||||||
cap.src_end = src+srcl;
|
cap.src_end = src+srcl;
|
||||||
while (n < max_s) {
|
while (n < max_s) {
|
||||||
const char *e;
|
const char *e;
|
||||||
@@ -505,17 +492,17 @@ static int str_gsub (lua_State *L) {
|
|||||||
e = match(L, src, p, &cap);
|
e = match(L, src, p, &cap);
|
||||||
if (e) {
|
if (e) {
|
||||||
n++;
|
n++;
|
||||||
add_s(L, &cap);
|
add_s(L, &b, &cap);
|
||||||
}
|
}
|
||||||
if (e && e>src) /* non empty match? */
|
if (e && e>src) /* non empty match? */
|
||||||
src = e; /* skip it */
|
src = e; /* skip it */
|
||||||
else if (src < cap.src_end)
|
else if (src < cap.src_end)
|
||||||
luaL_addchar(L, *src++);
|
luaL_putchar(&b, *src++);
|
||||||
else break;
|
else break;
|
||||||
if (anchor) break;
|
if (anchor) break;
|
||||||
}
|
}
|
||||||
addnchar(L, src, cap.src_end-src);
|
luaL_addlstring(&b, src, cap.src_end-src);
|
||||||
closeandpush(L);
|
luaL_pushresult(&b);
|
||||||
lua_pushnumber(L, n); /* number of substitutions */
|
lua_pushnumber(L, n); /* number of substitutions */
|
||||||
return 2;
|
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;
|
size_t l;
|
||||||
const char *s = luaL_check_lstr(L, arg, &l);
|
const char *s = luaL_check_lstr(L, arg, &l);
|
||||||
luaL_addchar(L, '"');
|
luaL_putchar(b, '"');
|
||||||
while (l--) {
|
while (l--) {
|
||||||
switch (*s) {
|
switch (*s) {
|
||||||
case '"': case '\\': case '\n':
|
case '"': case '\\': case '\n':
|
||||||
luaL_addchar(L, '\\');
|
luaL_putchar(b, '\\');
|
||||||
luaL_addchar(L, *s);
|
luaL_putchar(b, *s);
|
||||||
break;
|
break;
|
||||||
case '\0': addnchar(L, "\\000", 4); break;
|
case '\0': luaL_addlstring(b, "\\000", 4); break;
|
||||||
default: luaL_addchar(L, *s);
|
default: luaL_putchar(b, *s);
|
||||||
}
|
}
|
||||||
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') */
|
/* 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) {
|
static int str_format (lua_State *L) {
|
||||||
int arg = 1;
|
int arg = 1;
|
||||||
const char *strfrmt = luaL_check_string(L, arg);
|
const char *strfrmt = luaL_check_string(L, arg);
|
||||||
luaL_resetbuffer(L);
|
luaL_Buffer b;
|
||||||
|
luaL_buffinit(L, &b);
|
||||||
while (*strfrmt) {
|
while (*strfrmt) {
|
||||||
if (*strfrmt != '%')
|
if (*strfrmt != '%')
|
||||||
luaL_addchar(L, *strfrmt++);
|
luaL_putchar(&b, *strfrmt++);
|
||||||
else if (*++strfrmt == '%')
|
else if (*++strfrmt == '%')
|
||||||
luaL_addchar(L, *strfrmt++); /* %% */
|
luaL_putchar(&b, *strfrmt++); /* %% */
|
||||||
else { /* format item */
|
else { /* format item */
|
||||||
struct Capture cap;
|
struct Capture cap;
|
||||||
char form[MAX_FORMAT]; /* to store the format ('%...') */
|
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;
|
const char *initf = strfrmt;
|
||||||
form[0] = '%';
|
form[0] = '%';
|
||||||
if (isdigit((unsigned char)*initf) && *(initf+1) == '$') {
|
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)");
|
lua_error(L, "invalid format (width or precision too long)");
|
||||||
strncpy(form+1, initf, strfrmt-initf+1); /* +1 to include conversion */
|
strncpy(form+1, initf, strfrmt-initf+1); /* +1 to include conversion */
|
||||||
form[strfrmt-initf+2] = 0;
|
form[strfrmt-initf+2] = 0;
|
||||||
buff = luaL_openspace(L, 512); /* 512 > len(format('%99.99f', -1e308)) */
|
|
||||||
switch (*strfrmt++) {
|
switch (*strfrmt++) {
|
||||||
case 'c': case 'd': case 'i':
|
case 'c': case 'd': case 'i':
|
||||||
sprintf(buff, form, luaL_check_int(L, arg));
|
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));
|
sprintf(buff, form, luaL_check_number(L, arg));
|
||||||
break;
|
break;
|
||||||
case 'q':
|
case 'q':
|
||||||
luaI_addquoted(L, arg);
|
luaI_addquoted(L, &b, arg);
|
||||||
continue; /* skip the "addsize" at the end */
|
continue; /* skip the "addsize" at the end */
|
||||||
case 's': {
|
case 's': {
|
||||||
size_t l;
|
size_t l;
|
||||||
@@ -592,7 +581,8 @@ static int str_format (lua_State *L) {
|
|||||||
if (cap.capture[1].len == 0 && l >= 100) {
|
if (cap.capture[1].len == 0 && l >= 100) {
|
||||||
/* no precision and string is too long to be formatted;
|
/* no precision and string is too long to be formatted;
|
||||||
keep original string */
|
keep original string */
|
||||||
addnchar(L, s, l);
|
lua_pushvalue(L, arg);
|
||||||
|
luaL_addvalue(&b);
|
||||||
continue; /* skip the "addsize" at the end */
|
continue; /* skip the "addsize" at the end */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -603,10 +593,10 @@ static int str_format (lua_State *L) {
|
|||||||
default: /* also treat cases 'pnLlh' */
|
default: /* also treat cases 'pnLlh' */
|
||||||
lua_error(L, "invalid option in `format'");
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
** load bytecodes from files
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -86,7 +86,7 @@ static TString* LoadString (lua_State* L, ZIO* Z, int swap)
|
|||||||
return NULL;
|
return NULL;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char* s=luaL_openspace(L,size);
|
char* s=luaO_openspace(L,size);
|
||||||
LoadBlock(L,s,size,Z);
|
LoadBlock(L,s,size,Z);
|
||||||
return luaS_newlstr(L,s,size-1); /* remove trailing '\0' */
|
return luaS_newlstr(L,s,size-1); /* remove trailing '\0' */
|
||||||
}
|
}
|
||||||
|
|||||||
5
lvm.c
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
|
** Lua virtual machine
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -12,7 +12,6 @@
|
|||||||
#include "lua.h"
|
#include "lua.h"
|
||||||
|
|
||||||
#include "lapi.h"
|
#include "lapi.h"
|
||||||
#include "lauxlib.h"
|
|
||||||
#include "ldebug.h"
|
#include "ldebug.h"
|
||||||
#include "ldo.h"
|
#include "ldo.h"
|
||||||
#include "lfunc.h"
|
#include "lfunc.h"
|
||||||
@@ -300,7 +299,7 @@ void luaV_strconc (lua_State *L, int total, StkId top) {
|
|||||||
n++;
|
n++;
|
||||||
}
|
}
|
||||||
if (tl > MAX_SIZET) lua_error(L, "string size overflow");
|
if (tl > MAX_SIZET) lua_error(L, "string size overflow");
|
||||||
buffer = luaL_openspace(L, tl);
|
buffer = luaO_openspace(L, tl);
|
||||||
tl = 0;
|
tl = 0;
|
||||||
for (i=n; i>0; i--) { /* concat all strings */
|
for (i=n; i>0; i--) { /* concat all strings */
|
||||||
size_t l = tsvalue(top-i)->u.s.len;
|
size_t l = tsvalue(top-i)->u.s.len;
|
||||||
|
|||||||
Reference in New Issue
Block a user