mirror of https://github.com/rusefi/lua.git
support for strings with '\0'
This commit is contained in:
parent
5ef1989c4b
commit
88a2023c32
30
lapi.c
30
lapi.c
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: lapi.c,v 1.20 1998/01/27 19:13:45 roberto Exp roberto $
|
** $Id: lapi.c,v 1.21 1998/02/12 19:23:32 roberto Exp roberto $
|
||||||
** Lua API
|
** Lua API
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -219,7 +219,7 @@ lua_Object lua_getglobal (char *name)
|
||||||
lua_Object lua_rawgetglobal (char *name)
|
lua_Object lua_rawgetglobal (char *name)
|
||||||
{
|
{
|
||||||
TaggedString *ts = luaS_new(name);
|
TaggedString *ts = luaS_new(name);
|
||||||
return put_luaObject(&ts->u.globalval);
|
return put_luaObject(&ts->u.s.globalval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -293,6 +293,14 @@ char *lua_getstring (lua_Object object)
|
||||||
else return (svalue(Address(object)));
|
else return (svalue(Address(object)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
long lua_getstrlen (lua_Object object)
|
||||||
|
{
|
||||||
|
luaC_checkGC(); /* "tostring" may create a new string */
|
||||||
|
if (object == LUA_NOOBJECT || tostring(Address(object)))
|
||||||
|
return 0L;
|
||||||
|
else return (tsvalue(Address(object))->u.s.len);
|
||||||
|
}
|
||||||
|
|
||||||
void *lua_getuserdata (lua_Object object)
|
void *lua_getuserdata (lua_Object object)
|
||||||
{
|
{
|
||||||
if (object == LUA_NOOBJECT || ttype(Address(object)) != LUA_T_USERDATA)
|
if (object == LUA_NOOBJECT || ttype(Address(object)) != LUA_T_USERDATA)
|
||||||
|
@ -321,16 +329,20 @@ void lua_pushnumber (double n)
|
||||||
incr_top;
|
incr_top;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void lua_pushlstr (char *s, long len)
|
||||||
|
{
|
||||||
|
tsvalue(L->stack.top) = luaS_newlstr(s, len);
|
||||||
|
ttype(L->stack.top) = LUA_T_STRING;
|
||||||
|
incr_top;
|
||||||
|
luaC_checkGC();
|
||||||
|
}
|
||||||
|
|
||||||
void lua_pushstring (char *s)
|
void lua_pushstring (char *s)
|
||||||
{
|
{
|
||||||
if (s == NULL)
|
if (s == NULL)
|
||||||
ttype(L->stack.top) = LUA_T_NIL;
|
lua_pushnil();
|
||||||
else {
|
else
|
||||||
tsvalue(L->stack.top) = luaS_new(s);
|
lua_pushlstr(s, strlen(s));
|
||||||
ttype(L->stack.top) = LUA_T_STRING;
|
|
||||||
}
|
|
||||||
incr_top;
|
|
||||||
luaC_checkGC();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void lua_pushCclosure (lua_CFunction fn, int n)
|
void lua_pushCclosure (lua_CFunction fn, int n)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: lauxlib.c,v 1.8 1998/01/09 15:06:07 roberto Exp $
|
** $Id: lauxlib.c,v 1.8 1998/01/09 15:09:53 roberto Exp roberto $
|
||||||
** Auxiliar functions for building Lua libraries
|
** Auxiliar functions for building Lua libraries
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -31,17 +31,18 @@ void luaL_argerror (int numarg, char *extramsg)
|
||||||
numarg, funcname, extramsg);
|
numarg, funcname, extramsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *luaL_check_string (int numArg)
|
char *luaL_check_lstr (int numArg, long *len)
|
||||||
{
|
{
|
||||||
lua_Object o = lua_getparam(numArg);
|
lua_Object o = lua_getparam(numArg);
|
||||||
luaL_arg_check(lua_isstring(o), numArg, "string expected");
|
luaL_arg_check(lua_isstring(o), numArg, "string expected");
|
||||||
|
if (len) *len = lua_getstrlen(o);
|
||||||
return lua_getstring(o);
|
return lua_getstring(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *luaL_opt_string (int numArg, char *def)
|
char *luaL_opt_lstr (int numArg, char *def, long *len)
|
||||||
{
|
{
|
||||||
return (lua_getparam(numArg) == LUA_NOOBJECT) ? def :
|
return (lua_getparam(numArg) == LUA_NOOBJECT) ? def :
|
||||||
luaL_check_string(numArg);
|
luaL_check_lstr(numArg, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
double luaL_check_number (int numArg)
|
double luaL_check_number (int numArg)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: lauxlib.h,v 1.5 1997/12/17 20:48:58 roberto Exp roberto $
|
** $Id: lauxlib.h,v 1.6 1998/01/09 15:06:07 roberto Exp roberto $
|
||||||
** Auxiliar functions for building Lua libraries
|
** Auxiliar functions for building Lua libraries
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -23,8 +23,10 @@ struct luaL_reg {
|
||||||
|
|
||||||
void luaL_openlib (struct luaL_reg *l, int n);
|
void luaL_openlib (struct luaL_reg *l, int n);
|
||||||
void luaL_argerror (int numarg, char *extramsg);
|
void luaL_argerror (int numarg, char *extramsg);
|
||||||
char *luaL_check_string (int numArg);
|
#define luaL_check_string(n) (luaL_check_lstr((n), NULL))
|
||||||
char *luaL_opt_string (int numArg, char *def);
|
char *luaL_check_lstr (int numArg, long *len);
|
||||||
|
#define luaL_opt_string(n, d) (luaL_opt_lstr((n), (d), NULL))
|
||||||
|
char *luaL_opt_lstr (int numArg, char *def, long *len);
|
||||||
double luaL_check_number (int numArg);
|
double luaL_check_number (int numArg);
|
||||||
double luaL_opt_number (int numArg, double def);
|
double luaL_opt_number (int numArg, double def);
|
||||||
lua_Object luaL_functionarg (int arg);
|
lua_Object luaL_functionarg (int arg);
|
||||||
|
@ -34,6 +36,7 @@ void luaL_verror (char *fmt, ...);
|
||||||
char *luaL_openspace (int size);
|
char *luaL_openspace (int size);
|
||||||
void luaL_resetbuffer (void);
|
void luaL_resetbuffer (void);
|
||||||
void luaL_addchar (int c);
|
void luaL_addchar (int c);
|
||||||
|
int luaL_getsize (void);
|
||||||
void luaL_addsize (int n);
|
void luaL_addsize (int n);
|
||||||
int luaL_newbuffer (int size);
|
int luaL_newbuffer (int size);
|
||||||
void luaL_oldbuffer (int old);
|
void luaL_oldbuffer (int old);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: $
|
** $Id: lbuffer.c,v 1.1 1997/12/23 19:24:36 roberto Exp roberto $
|
||||||
** Auxiliar functions for building Lua libraries
|
** Auxiliar functions for building Lua libraries
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -57,6 +57,10 @@ void luaL_addsize (int n)
|
||||||
L->Mbuffnext += n;
|
L->Mbuffnext += n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int luaL_getsize (void)
|
||||||
|
{
|
||||||
|
return L->Mbuffnext-(L->Mbuffbase-L->Mbuffer);
|
||||||
|
}
|
||||||
|
|
||||||
int luaL_newbuffer (int size)
|
int luaL_newbuffer (int size)
|
||||||
{
|
{
|
||||||
|
|
25
lbuiltin.c
25
lbuiltin.c
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: lbuiltin.c,v 1.24 1998/02/12 19:23:32 roberto Exp roberto $
|
** $Id: lbuiltin.c,v 1.25 1998/02/12 19:27:10 roberto Exp roberto $
|
||||||
** Built-in functions
|
** Built-in functions
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -47,11 +47,11 @@ static void nextvar (void)
|
||||||
luaL_arg_check((GCnode *)g != g->head.next, 1, "variable name expected");
|
luaL_arg_check((GCnode *)g != g->head.next, 1, "variable name expected");
|
||||||
g = (TaggedString *)g->head.next;
|
g = (TaggedString *)g->head.next;
|
||||||
}
|
}
|
||||||
while (g && g->u.globalval.ttype == LUA_T_NIL) /* skip globals with nil */
|
while (g && g->u.s.globalval.ttype == LUA_T_NIL) /* skip globals with nil */
|
||||||
g = (TaggedString *)g->head.next;
|
g = (TaggedString *)g->head.next;
|
||||||
if (g) {
|
if (g) {
|
||||||
pushstring(g);
|
pushstring(g);
|
||||||
luaA_pushobject(&g->u.globalval);
|
luaA_pushobject(&g->u.s.globalval);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,12 +65,12 @@ static void foreachvar (void)
|
||||||
L->stack.top++;
|
L->stack.top++;
|
||||||
for (g = L->rootglobal.next; g; g = g->next) {
|
for (g = L->rootglobal.next; g; g = g->next) {
|
||||||
TaggedString *s = (TaggedString *)g;
|
TaggedString *s = (TaggedString *)g;
|
||||||
if (s->u.globalval.ttype != LUA_T_NIL) {
|
if (s->u.s.globalval.ttype != LUA_T_NIL) {
|
||||||
ttype(L->stack.stack+name) = LUA_T_STRING;
|
ttype(L->stack.stack+name) = LUA_T_STRING;
|
||||||
tsvalue(L->stack.stack+name) = s; /* keep s on stack to avoid GC */
|
tsvalue(L->stack.stack+name) = s; /* keep s on stack to avoid GC */
|
||||||
luaA_pushobject(&f);
|
luaA_pushobject(&f);
|
||||||
pushstring(s);
|
pushstring(s);
|
||||||
luaA_pushobject(&s->u.globalval);
|
luaA_pushobject(&s->u.s.globalval);
|
||||||
luaD_call((L->stack.top-L->stack.stack)-2, 1);
|
luaD_call((L->stack.top-L->stack.stack)-2, 1);
|
||||||
if (ttype(L->stack.top-1) != LUA_T_NIL)
|
if (ttype(L->stack.top-1) != LUA_T_NIL)
|
||||||
return;
|
return;
|
||||||
|
@ -331,22 +331,17 @@ static void copytagmethods (void)
|
||||||
|
|
||||||
static void rawgettable (void)
|
static void rawgettable (void)
|
||||||
{
|
{
|
||||||
lua_Object t = luaL_nonnullarg(1);
|
lua_pushobject(luaL_nonnullarg(1));
|
||||||
lua_Object i = luaL_nonnullarg(2);
|
lua_pushobject(luaL_nonnullarg(2));
|
||||||
lua_pushobject(t);
|
|
||||||
lua_pushobject(i);
|
|
||||||
lua_pushobject(lua_rawgettable());
|
lua_pushobject(lua_rawgettable());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void rawsettable (void)
|
static void rawsettable (void)
|
||||||
{
|
{
|
||||||
lua_Object t = luaL_nonnullarg(1);
|
lua_pushobject(luaL_nonnullarg(1));
|
||||||
lua_Object i = luaL_nonnullarg(2);
|
lua_pushobject(luaL_nonnullarg(2));
|
||||||
lua_Object v = luaL_nonnullarg(3);
|
lua_pushobject(luaL_nonnullarg(3));
|
||||||
lua_pushobject(t);
|
|
||||||
lua_pushobject(i);
|
|
||||||
lua_pushobject(v);
|
|
||||||
lua_rawsettable();
|
lua_rawsettable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
6
lgc.c
6
lgc.c
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: lgc.c,v 1.15 1998/01/09 14:44:55 roberto Exp roberto $
|
** $Id: lgc.c,v 1.16 1998/01/19 19:49:22 roberto Exp roberto $
|
||||||
** Garbage Collector
|
** Garbage Collector
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -213,8 +213,8 @@ static void globalmark (void)
|
||||||
{
|
{
|
||||||
TaggedString *g;
|
TaggedString *g;
|
||||||
for (g=(TaggedString *)L->rootglobal.next; g; g=(TaggedString *)g->head.next)
|
for (g=(TaggedString *)L->rootglobal.next; g; g=(TaggedString *)g->head.next)
|
||||||
if (g->u.globalval.ttype != LUA_T_NIL) {
|
if (g->u.s.globalval.ttype != LUA_T_NIL) {
|
||||||
markobject(&g->u.globalval);
|
markobject(&g->u.s.globalval);
|
||||||
strmark(g); /* cannot collect non nil global variables */
|
strmark(g); /* cannot collect non nil global variables */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
24
liolib.c
24
liolib.c
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: liolib.c,v 1.13 1997/12/26 18:38:16 roberto Exp roberto $
|
** $Id: liolib.c,v 1.14 1998/01/07 16:26:48 roberto Exp roberto $
|
||||||
** Standard I/O (and system) library
|
** Standard I/O (and system) library
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -184,7 +184,7 @@ static void io_read (void)
|
||||||
{
|
{
|
||||||
int arg = FIRSTARG;
|
int arg = FIRSTARG;
|
||||||
FILE *f = getfileparam(FINPUT, &arg);
|
FILE *f = getfileparam(FINPUT, &arg);
|
||||||
char *buff;
|
int l;
|
||||||
char *p = luaL_opt_string(arg, "[^\n]*{\n}");
|
char *p = luaL_opt_string(arg, "[^\n]*{\n}");
|
||||||
int inskip = 0; /* to control {skips} */
|
int inskip = 0; /* to control {skips} */
|
||||||
int c = NEED_OTHER;
|
int c = NEED_OTHER;
|
||||||
|
@ -204,11 +204,17 @@ static void io_read (void)
|
||||||
char *ep; /* get what is next */
|
char *ep; /* get what is next */
|
||||||
int m; /* match result */
|
int m; /* match result */
|
||||||
if (c == NEED_OTHER) c = getc(f);
|
if (c == NEED_OTHER) c = getc(f);
|
||||||
m = luaI_singlematch((c == EOF) ? 0 : (char)c, p, &ep);
|
if (c == EOF) {
|
||||||
|
luaI_singlematch(0, p, &ep); /* to set "ep" */
|
||||||
|
m = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m = luaI_singlematch((char)c, p, &ep);
|
||||||
if (m) {
|
if (m) {
|
||||||
if (inskip == 0) luaL_addchar(c);
|
if (inskip == 0) luaL_addchar(c);
|
||||||
c = NEED_OTHER;
|
c = NEED_OTHER;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
switch (*ep) {
|
switch (*ep) {
|
||||||
case '*': /* repetition */
|
case '*': /* repetition */
|
||||||
if (!m) p = ep+1; /* else stay in (repeat) the same item */
|
if (!m) p = ep+1; /* else stay in (repeat) the same item */
|
||||||
|
@ -225,10 +231,9 @@ static void io_read (void)
|
||||||
} break_while:
|
} break_while:
|
||||||
if (c >= 0) /* not EOF nor NEED_OTHER? */
|
if (c >= 0) /* not EOF nor NEED_OTHER? */
|
||||||
ungetc(c, f);
|
ungetc(c, f);
|
||||||
luaL_addchar(0);
|
l = luaL_getsize();
|
||||||
buff = luaL_buffer();
|
if (l > 0 || *p == 0) /* read something or did not fail? */
|
||||||
if (*buff != 0 || *p == 0) /* read something or did not fail? */
|
lua_pushlstr(luaL_buffer(), l);
|
||||||
lua_pushstring(buff);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -238,8 +243,9 @@ static void io_write (void)
|
||||||
FILE *f = getfileparam(FOUTPUT, &arg);
|
FILE *f = getfileparam(FOUTPUT, &arg);
|
||||||
int status = 1;
|
int status = 1;
|
||||||
char *s;
|
char *s;
|
||||||
while ((s = luaL_opt_string(arg++, NULL)) != NULL)
|
long l;
|
||||||
status = status && (fputs(s, f) != EOF);
|
while ((s = luaL_opt_lstr(arg++, NULL, &l)) != NULL)
|
||||||
|
status = status && (fwrite(s, 1, l, f) == l);
|
||||||
pushresult(status);
|
pushresult(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
6
llex.c
6
llex.c
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: llex.c,v 1.14 1998/01/19 20:18:02 roberto Exp roberto $
|
** $Id: llex.c,v 1.15 1998/02/11 20:56:46 roberto Exp roberto $
|
||||||
** Lexical Analizer
|
** Lexical Analizer
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -358,8 +358,8 @@ int luaY_lex (YYSTYPE *l)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
next(LS); /* skip delimiter */
|
next(LS); /* skip delimiter */
|
||||||
save(0);
|
l->pTStr = luaS_newlstr(L->Mbuffbase+1,
|
||||||
l->pTStr = luaS_new(L->Mbuffbase+1);
|
L->Mbuffnext-((L->Mbuffbase+1)-L->Mbuffer));
|
||||||
L->Mbuffer[L->Mbuffnext-1] = del; /* restore delimiter */
|
L->Mbuffer[L->Mbuffnext-1] = del; /* restore delimiter */
|
||||||
return STRING;
|
return STRING;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: lobject.h,v 1.15 1998/01/14 13:48:28 roberto Exp roberto $
|
** $Id: lobject.h,v 1.16 1998/01/19 19:49:22 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
|
||||||
*/
|
*/
|
||||||
|
@ -95,10 +95,13 @@ typedef struct GCnode {
|
||||||
|
|
||||||
typedef struct TaggedString {
|
typedef struct TaggedString {
|
||||||
GCnode head;
|
GCnode head;
|
||||||
int constindex; /* hint to reuse constants (= -1 if this is a userdata) */
|
|
||||||
unsigned long hash;
|
unsigned long hash;
|
||||||
|
int constindex; /* hint to reuse constants (= -1 if this is a userdata) */
|
||||||
union {
|
union {
|
||||||
|
struct {
|
||||||
TObject globalval;
|
TObject globalval;
|
||||||
|
long len; /* if this is a string, here is its length */
|
||||||
|
} s;
|
||||||
struct {
|
struct {
|
||||||
int tag;
|
int tag;
|
||||||
void *v; /* if this is a userdata, here is its value */
|
void *v; /* if this is a userdata, here is its value */
|
||||||
|
|
110
lstring.c
110
lstring.c
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: lstring.c,v 1.10 1998/01/13 18:06:27 roberto Exp roberto $
|
** $Id: lstring.c,v 1.11 1998/01/28 16:50:33 roberto Exp roberto $
|
||||||
** String table (keeps all strings handled by Lua)
|
** String table (keeps all strings handled by Lua)
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -21,7 +21,8 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static TaggedString EMPTY = {{NULL, 2}, 0, 0L, {{LUA_T_NIL, {NULL}}}, {0}};
|
static TaggedString EMPTY = {{NULL, 2}, 0L, 0,
|
||||||
|
{{{LUA_T_NIL, {NULL}}, 0L}}, {0}};
|
||||||
|
|
||||||
|
|
||||||
void luaS_init (void)
|
void luaS_init (void)
|
||||||
|
@ -36,20 +37,14 @@ void luaS_init (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static unsigned long hash (char *s, int tag)
|
static unsigned long hash_s (char *s, long l)
|
||||||
{
|
{
|
||||||
unsigned long h;
|
unsigned long h = 0;
|
||||||
if (tag != LUA_T_STRING)
|
while (l--)
|
||||||
h = (unsigned long)s;
|
|
||||||
else {
|
|
||||||
h = 0;
|
|
||||||
while (*s)
|
|
||||||
h = ((h<<5)-h)^(unsigned char)*(s++);
|
h = ((h<<5)-h)^(unsigned char)*(s++);
|
||||||
}
|
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int newsize (stringtable *tb)
|
static int newsize (stringtable *tb)
|
||||||
{
|
{
|
||||||
int size = tb->size;
|
int size = tb->size;
|
||||||
|
@ -91,34 +86,38 @@ static void grow (stringtable *tb)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static TaggedString *newone (char *buff, int tag, unsigned long h)
|
static TaggedString *newone_s (char *str, long l, unsigned long h)
|
||||||
{
|
{
|
||||||
TaggedString *ts;
|
TaggedString *ts = (TaggedString *)luaM_malloc(sizeof(TaggedString)+l);
|
||||||
if (tag == LUA_T_STRING) {
|
memcpy(ts->str, str, l);
|
||||||
long l = strlen(buff);
|
ts->str[l] = 0; /* ending 0 */
|
||||||
ts = (TaggedString *)luaM_malloc(sizeof(TaggedString)+l);
|
ts->u.s.globalval.ttype = LUA_T_NIL; /* initialize global value */
|
||||||
strcpy(ts->str, buff);
|
ts->u.s.len = l;
|
||||||
ts->u.globalval.ttype = LUA_T_NIL; /* initialize global value */
|
|
||||||
ts->constindex = 0;
|
ts->constindex = 0;
|
||||||
L->nblocks += gcsizestring(l);
|
L->nblocks += gcsizestring(l);
|
||||||
}
|
|
||||||
else {
|
|
||||||
ts = luaM_new(TaggedString);
|
|
||||||
ts->u.d.v = buff;
|
|
||||||
ts->u.d.tag = tag == LUA_ANYTAG ? 0 : tag;
|
|
||||||
ts->constindex = -1; /* tag -> this is a userdata */
|
|
||||||
L->nblocks++;
|
|
||||||
}
|
|
||||||
ts->head.marked = 0;
|
ts->head.marked = 0;
|
||||||
ts->head.next = (GCnode *)ts; /* signal it is in no list */
|
ts->head.next = (GCnode *)ts; /* signal it is in no list */
|
||||||
ts->hash = h;
|
ts->hash = h;
|
||||||
return ts;
|
return ts;
|
||||||
}
|
}
|
||||||
|
|
||||||
static TaggedString *insert (char *buff, int tag, stringtable *tb)
|
static TaggedString *newone_u (char *buff, int tag, unsigned long h)
|
||||||
|
{
|
||||||
|
TaggedString *ts = luaM_new(TaggedString);
|
||||||
|
ts->u.d.v = buff;
|
||||||
|
ts->u.d.tag = (tag == LUA_ANYTAG) ? 0 : tag;
|
||||||
|
ts->constindex = -1; /* tag -> this is a userdata */
|
||||||
|
L->nblocks++;
|
||||||
|
ts->head.marked = 0;
|
||||||
|
ts->head.next = (GCnode *)ts; /* signal it is in no list */
|
||||||
|
ts->hash = h;
|
||||||
|
return ts;
|
||||||
|
}
|
||||||
|
|
||||||
|
static TaggedString *insert_s (char *str, long l, stringtable *tb)
|
||||||
{
|
{
|
||||||
TaggedString *ts;
|
TaggedString *ts;
|
||||||
unsigned long h = hash(buff, tag);
|
unsigned long h = hash_s(str, l);
|
||||||
int size = tb->size;
|
int size = tb->size;
|
||||||
int i;
|
int i;
|
||||||
int j = -1;
|
int j = -1;
|
||||||
|
@ -129,9 +128,9 @@ static TaggedString *insert (char *buff, int tag, stringtable *tb)
|
||||||
for (i = h%size; (ts = tb->hash[i]) != NULL; ) {
|
for (i = h%size; (ts = tb->hash[i]) != NULL; ) {
|
||||||
if (ts == &EMPTY)
|
if (ts == &EMPTY)
|
||||||
j = i;
|
j = i;
|
||||||
else if ((ts->constindex >= 0) ? /* is a string? */
|
else if (ts->constindex >= 0 &&
|
||||||
(tag == LUA_T_STRING && (strcmp(buff, ts->str) == 0)) :
|
ts->u.s.len == l &&
|
||||||
((tag == ts->u.d.tag || tag == LUA_ANYTAG) && buff == ts->u.d.v))
|
(memcmp(str, ts->str, l) == 0))
|
||||||
return ts;
|
return ts;
|
||||||
if (++i == size) i=0;
|
if (++i == size) i=0;
|
||||||
}
|
}
|
||||||
|
@ -140,18 +139,53 @@ static TaggedString *insert (char *buff, int tag, stringtable *tb)
|
||||||
i = j;
|
i = j;
|
||||||
else
|
else
|
||||||
tb->nuse++;
|
tb->nuse++;
|
||||||
ts = tb->hash[i] = newone(buff, tag, h);
|
ts = tb->hash[i] = newone_s(str, l, h);
|
||||||
|
return ts;
|
||||||
|
}
|
||||||
|
|
||||||
|
static TaggedString *insert_u (void *buff, int tag, stringtable *tb)
|
||||||
|
{
|
||||||
|
TaggedString *ts;
|
||||||
|
unsigned long h = (unsigned long)buff;
|
||||||
|
int size = tb->size;
|
||||||
|
int i;
|
||||||
|
int j = -1;
|
||||||
|
if ((long)tb->nuse*3 >= (long)size*2) {
|
||||||
|
grow(tb);
|
||||||
|
size = tb->size;
|
||||||
|
}
|
||||||
|
for (i = h%size; (ts = tb->hash[i]) != NULL; ) {
|
||||||
|
if (ts == &EMPTY)
|
||||||
|
j = i;
|
||||||
|
else if (ts->constindex < 0 && /* is a udata? */
|
||||||
|
(tag == ts->u.d.tag || tag == LUA_ANYTAG) &&
|
||||||
|
buff == ts->u.d.v)
|
||||||
|
return ts;
|
||||||
|
if (++i == size) i=0;
|
||||||
|
}
|
||||||
|
/* not found */
|
||||||
|
if (j != -1) /* is there an EMPTY space? */
|
||||||
|
i = j;
|
||||||
|
else
|
||||||
|
tb->nuse++;
|
||||||
|
ts = tb->hash[i] = newone_u(buff, tag, h);
|
||||||
return ts;
|
return ts;
|
||||||
}
|
}
|
||||||
|
|
||||||
TaggedString *luaS_createudata (void *udata, int tag)
|
TaggedString *luaS_createudata (void *udata, int tag)
|
||||||
{
|
{
|
||||||
return insert(udata, tag, &L->string_root[(unsigned)udata%NUM_HASHS]);
|
return insert_u(udata, tag, &L->string_root[(unsigned)udata%NUM_HASHS]);
|
||||||
|
}
|
||||||
|
|
||||||
|
TaggedString *luaS_newlstr (char *str, long l)
|
||||||
|
{
|
||||||
|
int i = (l==0)?0:(unsigned char)str[0];
|
||||||
|
return insert_s(str, l, &L->string_root[i%NUM_HASHS]);
|
||||||
}
|
}
|
||||||
|
|
||||||
TaggedString *luaS_new (char *str)
|
TaggedString *luaS_new (char *str)
|
||||||
{
|
{
|
||||||
return insert(str, LUA_T_STRING, &L->string_root[(unsigned)str[0]%NUM_HASHS]);
|
return luaS_newlstr(str, strlen(str));
|
||||||
}
|
}
|
||||||
|
|
||||||
TaggedString *luaS_newfixedstring (char *str)
|
TaggedString *luaS_newfixedstring (char *str)
|
||||||
|
@ -167,7 +201,7 @@ void luaS_free (TaggedString *l)
|
||||||
{
|
{
|
||||||
while (l) {
|
while (l) {
|
||||||
TaggedString *next = (TaggedString *)l->head.next;
|
TaggedString *next = (TaggedString *)l->head.next;
|
||||||
L->nblocks -= (l->constindex == -1) ? 1 : gcsizestring(strlen(l->str));
|
L->nblocks -= (l->constindex == -1) ? 1 : gcsizestring(l->u.s.len);
|
||||||
luaM_free(l);
|
luaM_free(l);
|
||||||
l = next;
|
l = next;
|
||||||
}
|
}
|
||||||
|
@ -253,7 +287,7 @@ void luaS_freeall (void)
|
||||||
|
|
||||||
void luaS_rawsetglobal (TaggedString *ts, TObject *newval)
|
void luaS_rawsetglobal (TaggedString *ts, TObject *newval)
|
||||||
{
|
{
|
||||||
ts->u.globalval = *newval;
|
ts->u.s.globalval = *newval;
|
||||||
if (ts->head.next == (GCnode *)ts) { /* is not in list? */
|
if (ts->head.next == (GCnode *)ts) { /* is not in list? */
|
||||||
ts->head.next = L->rootglobal.next;
|
ts->head.next = L->rootglobal.next;
|
||||||
L->rootglobal.next = (GCnode *)ts;
|
L->rootglobal.next = (GCnode *)ts;
|
||||||
|
@ -265,7 +299,7 @@ char *luaS_travsymbol (int (*fn)(TObject *))
|
||||||
{
|
{
|
||||||
TaggedString *g;
|
TaggedString *g;
|
||||||
for (g=(TaggedString *)L->rootglobal.next; g; g=(TaggedString *)g->head.next)
|
for (g=(TaggedString *)L->rootglobal.next; g; g=(TaggedString *)g->head.next)
|
||||||
if (fn(&g->u.globalval))
|
if (fn(&g->u.s.globalval))
|
||||||
return g->str;
|
return g->str;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -274,6 +308,6 @@ char *luaS_travsymbol (int (*fn)(TObject *))
|
||||||
int luaS_globaldefined (char *name)
|
int luaS_globaldefined (char *name)
|
||||||
{
|
{
|
||||||
TaggedString *ts = luaS_new(name);
|
TaggedString *ts = luaS_new(name);
|
||||||
return ts->u.globalval.ttype != LUA_T_NIL;
|
return ts->u.s.globalval.ttype != LUA_T_NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: lstring.h,v 1.5 1997/11/26 18:53:45 roberto Exp roberto $
|
** $Id: lstring.h,v 1.6 1997/12/01 20:31:25 roberto Exp roberto $
|
||||||
** String table (keep all strings handled by Lua)
|
** String table (keep all strings handled by Lua)
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -15,6 +15,7 @@ void luaS_init (void);
|
||||||
TaggedString *luaS_createudata (void *udata, int tag);
|
TaggedString *luaS_createudata (void *udata, int tag);
|
||||||
TaggedString *luaS_collector (void);
|
TaggedString *luaS_collector (void);
|
||||||
void luaS_free (TaggedString *l);
|
void luaS_free (TaggedString *l);
|
||||||
|
TaggedString *luaS_newlstr (char *str, long l);
|
||||||
TaggedString *luaS_new (char *str);
|
TaggedString *luaS_new (char *str);
|
||||||
TaggedString *luaS_newfixedstring (char *str);
|
TaggedString *luaS_newfixedstring (char *str);
|
||||||
void luaS_rawsetglobal (TaggedString *ts, TObject *newval);
|
void luaS_rawsetglobal (TaggedString *ts, TObject *newval);
|
||||||
|
|
102
lstrlib.c
102
lstrlib.c
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: lstrlib.c,v 1.7 1998/01/09 14:57:43 roberto Exp roberto $
|
** $Id: lstrlib.c,v 1.8 1998/01/27 19:11:36 roberto Exp roberto $
|
||||||
** Standard library for strings and pattern-matching
|
** Standard library for strings and pattern-matching
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -19,83 +19,86 @@
|
||||||
static void addnchar (char *s, int n)
|
static void addnchar (char *s, int n)
|
||||||
{
|
{
|
||||||
char *b = luaL_openspace(n);
|
char *b = luaL_openspace(n);
|
||||||
strncpy(b, s, n);
|
memcpy(b, s, n);
|
||||||
luaL_addsize(n);
|
luaL_addsize(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void addstr (char *s)
|
|
||||||
{
|
|
||||||
addnchar(s, strlen(s));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void str_len (void)
|
static void str_len (void)
|
||||||
{
|
{
|
||||||
lua_pushnumber(strlen(luaL_check_string(1)));
|
long l;
|
||||||
|
luaL_check_lstr(1, &l);
|
||||||
|
lua_pushnumber(l);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void closeandpush (void)
|
static void closeandpush (void)
|
||||||
{
|
{
|
||||||
luaL_addchar(0);
|
lua_pushlstr(luaL_buffer(), luaL_getsize());
|
||||||
lua_pushstring(luaL_buffer());
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static long posrelat (long pos, long len)
|
||||||
|
{
|
||||||
|
/* relative string position: negative means back from end */
|
||||||
|
return (pos>=0) ? pos : len+pos+1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void str_sub (void)
|
static void str_sub (void)
|
||||||
{
|
{
|
||||||
char *s = luaL_check_string(1);
|
long l;
|
||||||
long l = strlen(s);
|
char *s = luaL_check_lstr(1, &l);
|
||||||
long start = (long)luaL_check_number(2);
|
long start = posrelat(luaL_check_number(2), l);
|
||||||
long end = (long)luaL_opt_number(3, -1);
|
long end = posrelat(luaL_opt_number(3, -1), l);
|
||||||
if (start < 0) start = l+start+1;
|
if (1 <= start && start <= end && end <= l)
|
||||||
if (end < 0) end = l+end+1;
|
lua_pushlstr(s+start-1, end-start+1);
|
||||||
if (1 <= start && start <= end && end <= l) {
|
|
||||||
luaL_resetbuffer();
|
|
||||||
addnchar(s+start-1, end-start+1);
|
|
||||||
closeandpush();
|
|
||||||
}
|
|
||||||
else lua_pushstring("");
|
else lua_pushstring("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void str_lower (void)
|
static void str_lower (void)
|
||||||
{
|
{
|
||||||
char *s;
|
long l;
|
||||||
|
int i;
|
||||||
|
char *s = luaL_check_lstr(1, &l);
|
||||||
luaL_resetbuffer();
|
luaL_resetbuffer();
|
||||||
for (s = luaL_check_string(1); *s; s++)
|
for (i=0; i<l; i++)
|
||||||
luaL_addchar(tolower((unsigned char)*s));
|
luaL_addchar(tolower((unsigned char)(s[i])));
|
||||||
closeandpush();
|
closeandpush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void str_upper (void)
|
static void str_upper (void)
|
||||||
{
|
{
|
||||||
char *s;
|
long l;
|
||||||
|
int i;
|
||||||
|
char *s = luaL_check_lstr(1, &l);
|
||||||
luaL_resetbuffer();
|
luaL_resetbuffer();
|
||||||
for (s = luaL_check_string(1); *s; s++)
|
for (i=0; i<l; i++)
|
||||||
luaL_addchar(toupper((unsigned char)*s));
|
luaL_addchar(toupper((unsigned char)(s[i])));
|
||||||
closeandpush();
|
closeandpush();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void str_rep (void)
|
static void str_rep (void)
|
||||||
{
|
{
|
||||||
char *s = luaL_check_string(1);
|
long l;
|
||||||
|
char *s = luaL_check_lstr(1, &l);
|
||||||
int n = (int)luaL_check_number(2);
|
int n = (int)luaL_check_number(2);
|
||||||
luaL_resetbuffer();
|
luaL_resetbuffer();
|
||||||
while (n-- > 0)
|
while (n-- > 0)
|
||||||
addstr(s);
|
addnchar(s, l);
|
||||||
closeandpush();
|
closeandpush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void str_ascii (void)
|
static void str_ascii (void)
|
||||||
{
|
{
|
||||||
char *s = luaL_check_string(1);
|
long l;
|
||||||
long pos = (long)luaL_opt_number(2, 1) - 1;
|
char *s = luaL_check_lstr(1, &l);
|
||||||
luaL_arg_check(0<=pos && pos<strlen(s), 2, "out of range");
|
long pos = posrelat(luaL_opt_number(2, 1), l);
|
||||||
lua_pushnumber((unsigned char)s[pos]);
|
luaL_arg_check(0<pos && pos<=l, 2, "out of range");
|
||||||
|
lua_pushnumber((unsigned char)s[pos-1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -124,14 +127,8 @@ struct Capture {
|
||||||
static void push_captures (struct Capture *cap)
|
static void push_captures (struct Capture *cap)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i=0; i<cap->level; i++) {
|
for (i=0; i<cap->level; i++)
|
||||||
int l = cap->capture[i].len;
|
lua_pushlstr(cap->capture[i].init, cap->capture[i].len);
|
||||||
char *buff = luaL_openspace(l+1);
|
|
||||||
if (l == -1) lua_error("unfinished capture");
|
|
||||||
strncpy(buff, cap->capture[i].init, l);
|
|
||||||
buff[l] = 0;
|
|
||||||
lua_pushstring(buff);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -163,7 +160,6 @@ static char *bracket_end (char *p)
|
||||||
static int matchclass (int c, int cl)
|
static int matchclass (int c, int cl)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
if (c == 0) return 0;
|
|
||||||
switch (tolower((unsigned char)cl)) {
|
switch (tolower((unsigned char)cl)) {
|
||||||
case 'w' : res = isalnum((unsigned char)c); break;
|
case 'w' : res = isalnum((unsigned char)c); break;
|
||||||
case 'd' : res = isdigit((unsigned char)c); break;
|
case 'd' : res = isdigit((unsigned char)c); break;
|
||||||
|
@ -184,7 +180,7 @@ int luaI_singlematch (int c, char *p, char **ep)
|
||||||
switch (*p) {
|
switch (*p) {
|
||||||
case '.':
|
case '.':
|
||||||
*ep = p+1;
|
*ep = p+1;
|
||||||
return (c != 0);
|
return 1;
|
||||||
case '\0':
|
case '\0':
|
||||||
*ep = p;
|
*ep = p;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -198,7 +194,6 @@ int luaI_singlematch (int c, char *p, char **ep)
|
||||||
int sig = *(p+1) == '^' ? (p++, 0) : 1;
|
int sig = *(p+1) == '^' ? (p++, 0) : 1;
|
||||||
if (end == NULL) lua_error("incorrect pattern (missing `]')");
|
if (end == NULL) lua_error("incorrect pattern (missing `]')");
|
||||||
*ep = end+1;
|
*ep = end+1;
|
||||||
if (c == 0) return 0;
|
|
||||||
while (++p < end) {
|
while (++p < end) {
|
||||||
if (*p == ESC) {
|
if (*p == ESC) {
|
||||||
if (((p+1) < end) && matchclass(c, *++p)) return sig;
|
if (((p+1) < end) && matchclass(c, *++p)) return sig;
|
||||||
|
@ -254,7 +249,8 @@ static char *matchitem (char *s, char *p, struct Capture *cap, char **ep)
|
||||||
}
|
}
|
||||||
else p--; /* and go through */
|
else p--; /* and go through */
|
||||||
}
|
}
|
||||||
return (luaI_singlematch(*s, p, ep) ? s+1 : NULL);
|
/* "luaI_singlematch" sets "ep" (so must be called even when *s == 0) */
|
||||||
|
return (luaI_singlematch(*s, p, ep) && *s) ? s+1 : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -322,10 +318,11 @@ static char *match (char *s, char *p, struct Capture *cap)
|
||||||
|
|
||||||
static void str_find (void)
|
static void str_find (void)
|
||||||
{
|
{
|
||||||
char *s = luaL_check_string(1);
|
long l;
|
||||||
|
char *s = luaL_check_lstr(1, &l);
|
||||||
char *p = luaL_check_string(2);
|
char *p = luaL_check_string(2);
|
||||||
long init = (long)luaL_opt_number(3, 1) - 1;
|
long init = posrelat(luaL_opt_number(3, 1), l) - 1;
|
||||||
luaL_arg_check(0 <= init && init <= strlen(s), 3, "out of range");
|
luaL_arg_check(0 <= init && init <= l, 3, "out of range");
|
||||||
if (lua_getparam(4) != LUA_NOOBJECT ||
|
if (lua_getparam(4) != LUA_NOOBJECT ||
|
||||||
strpbrk(p, SPECIALS) == NULL) { /* no special caracters? */
|
strpbrk(p, SPECIALS) == NULL) { /* no special caracters? */
|
||||||
char *s2 = strstr(s+init, p);
|
char *s2 = strstr(s+init, p);
|
||||||
|
@ -381,7 +378,10 @@ static void add_s (lua_Object newp, struct Capture *cap)
|
||||||
lua_error(NULL);
|
lua_error(NULL);
|
||||||
}
|
}
|
||||||
res = lua_getresult(1);
|
res = lua_getresult(1);
|
||||||
addstr(lua_isstring(res) ? lua_getstring(res) : "");
|
if (lua_isstring(res))
|
||||||
|
addnchar(lua_getstring(res), lua_getstrlen(res));
|
||||||
|
else
|
||||||
|
addnchar(NULL, 0);
|
||||||
lua_endblock();
|
lua_endblock();
|
||||||
}
|
}
|
||||||
else luaL_arg_check(0, 3, "string or function expected");
|
else luaL_arg_check(0, 3, "string or function expected");
|
||||||
|
@ -413,7 +413,7 @@ static void str_gsub (void)
|
||||||
else break;
|
else break;
|
||||||
if (anchor) break;
|
if (anchor) break;
|
||||||
}
|
}
|
||||||
addstr(src);
|
addnchar(src, strlen(src));
|
||||||
closeandpush();
|
closeandpush();
|
||||||
lua_pushnumber(n); /* number of substitutions */
|
lua_pushnumber(n); /* number of substitutions */
|
||||||
}
|
}
|
||||||
|
|
4
lua.h
4
lua.h
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: lua.h,v 1.14 1998/01/07 16:26:48 roberto Exp roberto $
|
** $Id: lua.h,v 1.15 1998/02/12 19:23:32 roberto Exp roberto $
|
||||||
** Lua - An Extensible Extension Language
|
** Lua - An Extensible Extension Language
|
||||||
** TeCGraf: Grupo de Tecnologia em Computacao Grafica, PUC-Rio, Brazil
|
** TeCGraf: Grupo de Tecnologia em Computacao Grafica, PUC-Rio, Brazil
|
||||||
** e-mail: lua@tecgraf.puc-rio.br
|
** e-mail: lua@tecgraf.puc-rio.br
|
||||||
|
@ -90,12 +90,14 @@ int lua_isfunction (lua_Object object);
|
||||||
|
|
||||||
double lua_getnumber (lua_Object object);
|
double lua_getnumber (lua_Object object);
|
||||||
char *lua_getstring (lua_Object object);
|
char *lua_getstring (lua_Object object);
|
||||||
|
long lua_getstrlen (lua_Object object);
|
||||||
lua_CFunction lua_getcfunction (lua_Object object);
|
lua_CFunction lua_getcfunction (lua_Object object);
|
||||||
void *lua_getuserdata (lua_Object object);
|
void *lua_getuserdata (lua_Object object);
|
||||||
|
|
||||||
|
|
||||||
void lua_pushnil (void);
|
void lua_pushnil (void);
|
||||||
void lua_pushnumber (double n);
|
void lua_pushnumber (double n);
|
||||||
|
void lua_pushlstr (char *s, long len);
|
||||||
void lua_pushstring (char *s);
|
void lua_pushstring (char *s);
|
||||||
void lua_pushCclosure (lua_CFunction fn, int n);
|
void lua_pushCclosure (lua_CFunction fn, int n);
|
||||||
void lua_pushusertag (void *u, int tag);
|
void lua_pushusertag (void *u, int tag);
|
||||||
|
|
41
lvm.c
41
lvm.c
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: lvm.c,v 1.22 1998/01/12 13:35:37 roberto Exp roberto $
|
** $Id: lvm.c,v 1.23 1998/01/14 13:49:15 roberto Exp roberto $
|
||||||
** Lua virtual machine
|
** Lua virtual machine
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -37,13 +37,14 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static TaggedString *strconc (char *l, char *r)
|
static TaggedString *strconc (TaggedString *l, TaggedString *r)
|
||||||
{
|
{
|
||||||
size_t nl = strlen(l);
|
size_t nl = l->u.s.len;
|
||||||
char *buffer = luaL_openspace(nl+strlen(r)+1);
|
size_t nr = r->u.s.len;
|
||||||
strcpy(buffer, l);
|
char *buffer = luaL_openspace(nl+nr+1);
|
||||||
strcpy(buffer+nl, r);
|
memcpy(buffer, l->str, nl);
|
||||||
return luaS_new(buffer);
|
memcpy(buffer+nl, r->str, nr);
|
||||||
|
return luaS_newlstr(buffer, nl+nr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -167,7 +168,7 @@ void luaV_settable (TObject *t, int mode)
|
||||||
void luaV_getglobal (TaggedString *ts)
|
void luaV_getglobal (TaggedString *ts)
|
||||||
{
|
{
|
||||||
/* WARNING: caller must assure stack space */
|
/* WARNING: caller must assure stack space */
|
||||||
TObject *value = &ts->u.globalval;
|
TObject *value = &ts->u.s.globalval;
|
||||||
TObject *im = luaT_getimbyObj(value, IM_GETGLOBAL);
|
TObject *im = luaT_getimbyObj(value, IM_GETGLOBAL);
|
||||||
if (ttype(im) == LUA_T_NIL) { /* default behavior */
|
if (ttype(im) == LUA_T_NIL) { /* default behavior */
|
||||||
*L->stack.top++ = *value;
|
*L->stack.top++ = *value;
|
||||||
|
@ -185,7 +186,7 @@ void luaV_getglobal (TaggedString *ts)
|
||||||
|
|
||||||
void luaV_setglobal (TaggedString *ts)
|
void luaV_setglobal (TaggedString *ts)
|
||||||
{
|
{
|
||||||
TObject *oldvalue = &ts->u.globalval;
|
TObject *oldvalue = &ts->u.s.globalval;
|
||||||
TObject *im = luaT_getimbyObj(oldvalue, IM_SETGLOBAL);
|
TObject *im = luaT_getimbyObj(oldvalue, IM_SETGLOBAL);
|
||||||
if (ttype(im) == LUA_T_NIL) /* default behavior */
|
if (ttype(im) == LUA_T_NIL) /* default behavior */
|
||||||
luaS_rawsetglobal(ts, --L->stack.top);
|
luaS_rawsetglobal(ts, --L->stack.top);
|
||||||
|
@ -224,6 +225,23 @@ static void call_arith (IMS event)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int strcomp (char *l, long ll, char *r, long lr)
|
||||||
|
{
|
||||||
|
for (;;) {
|
||||||
|
long temp = strcoll(l, r);
|
||||||
|
if (temp != 0) return temp;
|
||||||
|
/* strings are equal up to a '\0' */
|
||||||
|
temp = strlen(l); /* index of first '\0' in both strings */
|
||||||
|
if (temp == ll) /* l is finished? */
|
||||||
|
return (temp == lr) ? 0 : -1; /* l is equal or smaller than r */
|
||||||
|
else if (temp == lr) /* r is finished? */
|
||||||
|
return 1; /* l is greater than r (because l is not finished) */
|
||||||
|
/* both strings longer than temp; go on comparing (after the '\0') */
|
||||||
|
temp++;
|
||||||
|
l += temp; ll -= temp; r += temp; lr -= temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void comparison (lua_Type ttype_less, lua_Type ttype_equal,
|
static void comparison (lua_Type ttype_less, lua_Type ttype_equal,
|
||||||
lua_Type ttype_great, IMS op)
|
lua_Type ttype_great, IMS op)
|
||||||
{
|
{
|
||||||
|
@ -234,7 +252,8 @@ static void comparison (lua_Type ttype_less, lua_Type ttype_equal,
|
||||||
if (ttype(l) == LUA_T_NUMBER && ttype(r) == LUA_T_NUMBER)
|
if (ttype(l) == LUA_T_NUMBER && ttype(r) == LUA_T_NUMBER)
|
||||||
result = (nvalue(l) < nvalue(r)) ? -1 : (nvalue(l) == nvalue(r)) ? 0 : 1;
|
result = (nvalue(l) < nvalue(r)) ? -1 : (nvalue(l) == nvalue(r)) ? 0 : 1;
|
||||||
else if (ttype(l) == LUA_T_STRING && ttype(r) == LUA_T_STRING)
|
else if (ttype(l) == LUA_T_STRING && ttype(r) == LUA_T_STRING)
|
||||||
result = strcoll(svalue(l), svalue(r));
|
result = strcomp(svalue(l), tsvalue(l)->u.s.len,
|
||||||
|
svalue(r), tsvalue(r)->u.s.len);
|
||||||
else {
|
else {
|
||||||
call_binTM(op, "unexpected type in comparison");
|
call_binTM(op, "unexpected type in comparison");
|
||||||
return;
|
return;
|
||||||
|
@ -582,7 +601,7 @@ StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base)
|
||||||
if (tostring(l) || tostring(r))
|
if (tostring(l) || tostring(r))
|
||||||
call_binTM(IM_CONCAT, "unexpected type for concatenation");
|
call_binTM(IM_CONCAT, "unexpected type for concatenation");
|
||||||
else {
|
else {
|
||||||
tsvalue(l) = strconc(svalue(l), svalue(r));
|
tsvalue(l) = strconc(tsvalue(l), tsvalue(r));
|
||||||
--S->top;
|
--S->top;
|
||||||
}
|
}
|
||||||
luaC_checkGC();
|
luaC_checkGC();
|
||||||
|
|
Loading…
Reference in New Issue