diff options
| -rw-r--r-- | lapi.c | 30 | ||||
| -rw-r--r-- | lauxlib.c | 9 | ||||
| -rw-r--r-- | lauxlib.h | 9 | ||||
| -rw-r--r-- | lbuffer.c | 6 | ||||
| -rw-r--r-- | lbuiltin.c | 25 | ||||
| -rw-r--r-- | lgc.c | 6 | ||||
| -rw-r--r-- | liolib.c | 30 | ||||
| -rw-r--r-- | llex.c | 6 | ||||
| -rw-r--r-- | lobject.h | 9 | ||||
| -rw-r--r-- | lstring.c | 116 | ||||
| -rw-r--r-- | lstring.h | 3 | ||||
| -rw-r--r-- | lstrlib.c | 98 | ||||
| -rw-r--r-- | lua.h | 4 | ||||
| -rw-r--r-- | lvm.c | 41 |
14 files changed, 236 insertions, 156 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lapi.c,v 1.20 1998/01/27 19:13:45 roberto Exp roberto $ | 2 | ** $Id: lapi.c,v 1.21 1998/02/12 19:23:32 roberto Exp roberto $ |
| 3 | ** Lua API | 3 | ** Lua API |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -219,7 +219,7 @@ lua_Object lua_getglobal (char *name) | |||
| 219 | lua_Object lua_rawgetglobal (char *name) | 219 | lua_Object lua_rawgetglobal (char *name) |
| 220 | { | 220 | { |
| 221 | TaggedString *ts = luaS_new(name); | 221 | TaggedString *ts = luaS_new(name); |
| 222 | return put_luaObject(&ts->u.globalval); | 222 | return put_luaObject(&ts->u.s.globalval); |
| 223 | } | 223 | } |
| 224 | 224 | ||
| 225 | 225 | ||
| @@ -293,6 +293,14 @@ char *lua_getstring (lua_Object object) | |||
| 293 | else return (svalue(Address(object))); | 293 | else return (svalue(Address(object))); |
| 294 | } | 294 | } |
| 295 | 295 | ||
| 296 | long lua_getstrlen (lua_Object object) | ||
| 297 | { | ||
| 298 | luaC_checkGC(); /* "tostring" may create a new string */ | ||
| 299 | if (object == LUA_NOOBJECT || tostring(Address(object))) | ||
| 300 | return 0L; | ||
| 301 | else return (tsvalue(Address(object))->u.s.len); | ||
| 302 | } | ||
| 303 | |||
| 296 | void *lua_getuserdata (lua_Object object) | 304 | void *lua_getuserdata (lua_Object object) |
| 297 | { | 305 | { |
| 298 | if (object == LUA_NOOBJECT || ttype(Address(object)) != LUA_T_USERDATA) | 306 | if (object == LUA_NOOBJECT || ttype(Address(object)) != LUA_T_USERDATA) |
| @@ -321,18 +329,22 @@ void lua_pushnumber (double n) | |||
| 321 | incr_top; | 329 | incr_top; |
| 322 | } | 330 | } |
| 323 | 331 | ||
| 324 | void lua_pushstring (char *s) | 332 | void lua_pushlstr (char *s, long len) |
| 325 | { | 333 | { |
| 326 | if (s == NULL) | 334 | tsvalue(L->stack.top) = luaS_newlstr(s, len); |
| 327 | ttype(L->stack.top) = LUA_T_NIL; | 335 | ttype(L->stack.top) = LUA_T_STRING; |
| 328 | else { | ||
| 329 | tsvalue(L->stack.top) = luaS_new(s); | ||
| 330 | ttype(L->stack.top) = LUA_T_STRING; | ||
| 331 | } | ||
| 332 | incr_top; | 336 | incr_top; |
| 333 | luaC_checkGC(); | 337 | luaC_checkGC(); |
| 334 | } | 338 | } |
| 335 | 339 | ||
| 340 | void lua_pushstring (char *s) | ||
| 341 | { | ||
| 342 | if (s == NULL) | ||
| 343 | lua_pushnil(); | ||
| 344 | else | ||
| 345 | lua_pushlstr(s, strlen(s)); | ||
| 346 | } | ||
| 347 | |||
| 336 | void lua_pushCclosure (lua_CFunction fn, int n) | 348 | void lua_pushCclosure (lua_CFunction fn, int n) |
| 337 | { | 349 | { |
| 338 | if (fn == NULL) | 350 | if (fn == NULL) |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lauxlib.c,v 1.8 1998/01/09 15:06:07 roberto Exp $ | 2 | ** $Id: lauxlib.c,v 1.8 1998/01/09 15:09:53 roberto Exp roberto $ |
| 3 | ** Auxiliar functions for building Lua libraries | 3 | ** Auxiliar functions for building Lua libraries |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -31,17 +31,18 @@ void luaL_argerror (int numarg, char *extramsg) | |||
| 31 | numarg, funcname, extramsg); | 31 | numarg, funcname, extramsg); |
| 32 | } | 32 | } |
| 33 | 33 | ||
| 34 | char *luaL_check_string (int numArg) | 34 | char *luaL_check_lstr (int numArg, long *len) |
| 35 | { | 35 | { |
| 36 | lua_Object o = lua_getparam(numArg); | 36 | lua_Object o = lua_getparam(numArg); |
| 37 | luaL_arg_check(lua_isstring(o), numArg, "string expected"); | 37 | luaL_arg_check(lua_isstring(o), numArg, "string expected"); |
| 38 | if (len) *len = lua_getstrlen(o); | ||
| 38 | return lua_getstring(o); | 39 | return lua_getstring(o); |
| 39 | } | 40 | } |
| 40 | 41 | ||
| 41 | char *luaL_opt_string (int numArg, char *def) | 42 | char *luaL_opt_lstr (int numArg, char *def, long *len) |
| 42 | { | 43 | { |
| 43 | return (lua_getparam(numArg) == LUA_NOOBJECT) ? def : | 44 | return (lua_getparam(numArg) == LUA_NOOBJECT) ? def : |
| 44 | luaL_check_string(numArg); | 45 | luaL_check_lstr(numArg, len); |
| 45 | } | 46 | } |
| 46 | 47 | ||
| 47 | double luaL_check_number (int numArg) | 48 | double luaL_check_number (int numArg) |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lauxlib.h,v 1.5 1997/12/17 20:48:58 roberto Exp roberto $ | 2 | ** $Id: lauxlib.h,v 1.6 1998/01/09 15:06:07 roberto Exp roberto $ |
| 3 | ** Auxiliar functions for building Lua libraries | 3 | ** Auxiliar functions for building Lua libraries |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -23,8 +23,10 @@ struct luaL_reg { | |||
| 23 | 23 | ||
| 24 | void luaL_openlib (struct luaL_reg *l, int n); | 24 | void luaL_openlib (struct luaL_reg *l, int n); |
| 25 | void luaL_argerror (int numarg, char *extramsg); | 25 | void luaL_argerror (int numarg, char *extramsg); |
| 26 | char *luaL_check_string (int numArg); | 26 | #define luaL_check_string(n) (luaL_check_lstr((n), NULL)) |
| 27 | char *luaL_opt_string (int numArg, char *def); | 27 | char *luaL_check_lstr (int numArg, long *len); |
| 28 | #define luaL_opt_string(n, d) (luaL_opt_lstr((n), (d), NULL)) | ||
| 29 | char *luaL_opt_lstr (int numArg, char *def, long *len); | ||
| 28 | double luaL_check_number (int numArg); | 30 | double luaL_check_number (int numArg); |
| 29 | double luaL_opt_number (int numArg, double def); | 31 | double luaL_opt_number (int numArg, double def); |
| 30 | lua_Object luaL_functionarg (int arg); | 32 | lua_Object luaL_functionarg (int arg); |
| @@ -34,6 +36,7 @@ void luaL_verror (char *fmt, ...); | |||
| 34 | char *luaL_openspace (int size); | 36 | char *luaL_openspace (int size); |
| 35 | void luaL_resetbuffer (void); | 37 | void luaL_resetbuffer (void); |
| 36 | void luaL_addchar (int c); | 38 | void luaL_addchar (int c); |
| 39 | int luaL_getsize (void); | ||
| 37 | void luaL_addsize (int n); | 40 | void luaL_addsize (int n); |
| 38 | int luaL_newbuffer (int size); | 41 | int luaL_newbuffer (int size); |
| 39 | void luaL_oldbuffer (int old); | 42 | void luaL_oldbuffer (int old); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: $ | 2 | ** $Id: lbuffer.c,v 1.1 1997/12/23 19:24:36 roberto Exp roberto $ |
| 3 | ** Auxiliar functions for building Lua libraries | 3 | ** Auxiliar functions for building Lua libraries |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -57,6 +57,10 @@ void luaL_addsize (int n) | |||
| 57 | L->Mbuffnext += n; | 57 | L->Mbuffnext += n; |
| 58 | } | 58 | } |
| 59 | 59 | ||
| 60 | int luaL_getsize (void) | ||
| 61 | { | ||
| 62 | return L->Mbuffnext-(L->Mbuffbase-L->Mbuffer); | ||
| 63 | } | ||
| 60 | 64 | ||
| 61 | int luaL_newbuffer (int size) | 65 | int luaL_newbuffer (int size) |
| 62 | { | 66 | { |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lbuiltin.c,v 1.24 1998/02/12 19:23:32 roberto Exp roberto $ | 2 | ** $Id: lbuiltin.c,v 1.25 1998/02/12 19:27:10 roberto Exp roberto $ |
| 3 | ** Built-in functions | 3 | ** Built-in functions |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -47,11 +47,11 @@ static void nextvar (void) | |||
| 47 | luaL_arg_check((GCnode *)g != g->head.next, 1, "variable name expected"); | 47 | luaL_arg_check((GCnode *)g != g->head.next, 1, "variable name expected"); |
| 48 | g = (TaggedString *)g->head.next; | 48 | g = (TaggedString *)g->head.next; |
| 49 | } | 49 | } |
| 50 | while (g && g->u.globalval.ttype == LUA_T_NIL) /* skip globals with nil */ | 50 | while (g && g->u.s.globalval.ttype == LUA_T_NIL) /* skip globals with nil */ |
| 51 | g = (TaggedString *)g->head.next; | 51 | g = (TaggedString *)g->head.next; |
| 52 | if (g) { | 52 | if (g) { |
| 53 | pushstring(g); | 53 | pushstring(g); |
| 54 | luaA_pushobject(&g->u.globalval); | 54 | luaA_pushobject(&g->u.s.globalval); |
| 55 | } | 55 | } |
| 56 | } | 56 | } |
| 57 | 57 | ||
| @@ -65,12 +65,12 @@ static void foreachvar (void) | |||
| 65 | L->stack.top++; | 65 | L->stack.top++; |
| 66 | for (g = L->rootglobal.next; g; g = g->next) { | 66 | for (g = L->rootglobal.next; g; g = g->next) { |
| 67 | TaggedString *s = (TaggedString *)g; | 67 | TaggedString *s = (TaggedString *)g; |
| 68 | if (s->u.globalval.ttype != LUA_T_NIL) { | 68 | if (s->u.s.globalval.ttype != LUA_T_NIL) { |
| 69 | ttype(L->stack.stack+name) = LUA_T_STRING; | 69 | ttype(L->stack.stack+name) = LUA_T_STRING; |
| 70 | tsvalue(L->stack.stack+name) = s; /* keep s on stack to avoid GC */ | 70 | tsvalue(L->stack.stack+name) = s; /* keep s on stack to avoid GC */ |
| 71 | luaA_pushobject(&f); | 71 | luaA_pushobject(&f); |
| 72 | pushstring(s); | 72 | pushstring(s); |
| 73 | luaA_pushobject(&s->u.globalval); | 73 | luaA_pushobject(&s->u.s.globalval); |
| 74 | luaD_call((L->stack.top-L->stack.stack)-2, 1); | 74 | luaD_call((L->stack.top-L->stack.stack)-2, 1); |
| 75 | if (ttype(L->stack.top-1) != LUA_T_NIL) | 75 | if (ttype(L->stack.top-1) != LUA_T_NIL) |
| 76 | return; | 76 | return; |
| @@ -331,22 +331,17 @@ static void copytagmethods (void) | |||
| 331 | 331 | ||
| 332 | static void rawgettable (void) | 332 | static void rawgettable (void) |
| 333 | { | 333 | { |
| 334 | lua_Object t = luaL_nonnullarg(1); | 334 | lua_pushobject(luaL_nonnullarg(1)); |
| 335 | lua_Object i = luaL_nonnullarg(2); | 335 | lua_pushobject(luaL_nonnullarg(2)); |
| 336 | lua_pushobject(t); | ||
| 337 | lua_pushobject(i); | ||
| 338 | lua_pushobject(lua_rawgettable()); | 336 | lua_pushobject(lua_rawgettable()); |
| 339 | } | 337 | } |
| 340 | 338 | ||
| 341 | 339 | ||
| 342 | static void rawsettable (void) | 340 | static void rawsettable (void) |
| 343 | { | 341 | { |
| 344 | lua_Object t = luaL_nonnullarg(1); | 342 | lua_pushobject(luaL_nonnullarg(1)); |
| 345 | lua_Object i = luaL_nonnullarg(2); | 343 | lua_pushobject(luaL_nonnullarg(2)); |
| 346 | lua_Object v = luaL_nonnullarg(3); | 344 | lua_pushobject(luaL_nonnullarg(3)); |
| 347 | lua_pushobject(t); | ||
| 348 | lua_pushobject(i); | ||
| 349 | lua_pushobject(v); | ||
| 350 | lua_rawsettable(); | 345 | lua_rawsettable(); |
| 351 | } | 346 | } |
| 352 | 347 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lgc.c,v 1.15 1998/01/09 14:44:55 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 1.16 1998/01/19 19:49:22 roberto Exp roberto $ |
| 3 | ** Garbage Collector | 3 | ** Garbage Collector |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -213,8 +213,8 @@ static void globalmark (void) | |||
| 213 | { | 213 | { |
| 214 | TaggedString *g; | 214 | TaggedString *g; |
| 215 | for (g=(TaggedString *)L->rootglobal.next; g; g=(TaggedString *)g->head.next) | 215 | for (g=(TaggedString *)L->rootglobal.next; g; g=(TaggedString *)g->head.next) |
| 216 | if (g->u.globalval.ttype != LUA_T_NIL) { | 216 | if (g->u.s.globalval.ttype != LUA_T_NIL) { |
| 217 | markobject(&g->u.globalval); | 217 | markobject(&g->u.s.globalval); |
| 218 | strmark(g); /* cannot collect non nil global variables */ | 218 | strmark(g); /* cannot collect non nil global variables */ |
| 219 | } | 219 | } |
| 220 | } | 220 | } |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: liolib.c,v 1.13 1997/12/26 18:38:16 roberto Exp roberto $ | 2 | ** $Id: liolib.c,v 1.14 1998/01/07 16:26:48 roberto Exp roberto $ |
| 3 | ** Standard I/O (and system) library | 3 | ** Standard I/O (and system) library |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -184,7 +184,7 @@ static void io_read (void) | |||
| 184 | { | 184 | { |
| 185 | int arg = FIRSTARG; | 185 | int arg = FIRSTARG; |
| 186 | FILE *f = getfileparam(FINPUT, &arg); | 186 | FILE *f = getfileparam(FINPUT, &arg); |
| 187 | char *buff; | 187 | int l; |
| 188 | char *p = luaL_opt_string(arg, "[^\n]*{\n}"); | 188 | char *p = luaL_opt_string(arg, "[^\n]*{\n}"); |
| 189 | int inskip = 0; /* to control {skips} */ | 189 | int inskip = 0; /* to control {skips} */ |
| 190 | int c = NEED_OTHER; | 190 | int c = NEED_OTHER; |
| @@ -204,10 +204,16 @@ static void io_read (void) | |||
| 204 | char *ep; /* get what is next */ | 204 | char *ep; /* get what is next */ |
| 205 | int m; /* match result */ | 205 | int m; /* match result */ |
| 206 | if (c == NEED_OTHER) c = getc(f); | 206 | if (c == NEED_OTHER) c = getc(f); |
| 207 | m = luaI_singlematch((c == EOF) ? 0 : (char)c, p, &ep); | 207 | if (c == EOF) { |
| 208 | if (m) { | 208 | luaI_singlematch(0, p, &ep); /* to set "ep" */ |
| 209 | if (inskip == 0) luaL_addchar(c); | 209 | m = 0; |
| 210 | c = NEED_OTHER; | 210 | } |
| 211 | else { | ||
| 212 | m = luaI_singlematch((char)c, p, &ep); | ||
| 213 | if (m) { | ||
| 214 | if (inskip == 0) luaL_addchar(c); | ||
| 215 | c = NEED_OTHER; | ||
| 216 | } | ||
| 211 | } | 217 | } |
| 212 | switch (*ep) { | 218 | switch (*ep) { |
| 213 | case '*': /* repetition */ | 219 | case '*': /* repetition */ |
| @@ -225,10 +231,9 @@ static void io_read (void) | |||
| 225 | } break_while: | 231 | } break_while: |
| 226 | if (c >= 0) /* not EOF nor NEED_OTHER? */ | 232 | if (c >= 0) /* not EOF nor NEED_OTHER? */ |
| 227 | ungetc(c, f); | 233 | ungetc(c, f); |
| 228 | luaL_addchar(0); | 234 | l = luaL_getsize(); |
| 229 | buff = luaL_buffer(); | 235 | if (l > 0 || *p == 0) /* read something or did not fail? */ |
| 230 | if (*buff != 0 || *p == 0) /* read something or did not fail? */ | 236 | lua_pushlstr(luaL_buffer(), l); |
| 231 | lua_pushstring(buff); | ||
| 232 | } | 237 | } |
| 233 | 238 | ||
| 234 | 239 | ||
| @@ -238,8 +243,9 @@ static void io_write (void) | |||
| 238 | FILE *f = getfileparam(FOUTPUT, &arg); | 243 | FILE *f = getfileparam(FOUTPUT, &arg); |
| 239 | int status = 1; | 244 | int status = 1; |
| 240 | char *s; | 245 | char *s; |
| 241 | while ((s = luaL_opt_string(arg++, NULL)) != NULL) | 246 | long l; |
| 242 | status = status && (fputs(s, f) != EOF); | 247 | while ((s = luaL_opt_lstr(arg++, NULL, &l)) != NULL) |
| 248 | status = status && (fwrite(s, 1, l, f) == l); | ||
| 243 | pushresult(status); | 249 | pushresult(status); |
| 244 | } | 250 | } |
| 245 | 251 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: llex.c,v 1.14 1998/01/19 20:18:02 roberto Exp roberto $ | 2 | ** $Id: llex.c,v 1.15 1998/02/11 20:56:46 roberto Exp roberto $ |
| 3 | ** Lexical Analizer | 3 | ** Lexical Analizer |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -358,8 +358,8 @@ int luaY_lex (YYSTYPE *l) | |||
| 358 | } | 358 | } |
| 359 | } | 359 | } |
| 360 | next(LS); /* skip delimiter */ | 360 | next(LS); /* skip delimiter */ |
| 361 | save(0); | 361 | l->pTStr = luaS_newlstr(L->Mbuffbase+1, |
| 362 | l->pTStr = luaS_new(L->Mbuffbase+1); | 362 | L->Mbuffnext-((L->Mbuffbase+1)-L->Mbuffer)); |
| 363 | L->Mbuffer[L->Mbuffnext-1] = del; /* restore delimiter */ | 363 | L->Mbuffer[L->Mbuffnext-1] = del; /* restore delimiter */ |
| 364 | return STRING; | 364 | return STRING; |
| 365 | } | 365 | } |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lobject.h,v 1.15 1998/01/14 13:48:28 roberto Exp roberto $ | 2 | ** $Id: lobject.h,v 1.16 1998/01/19 19:49:22 roberto Exp roberto $ |
| 3 | ** Type definitions for Lua objects | 3 | ** Type definitions for Lua objects |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -95,10 +95,13 @@ typedef struct GCnode { | |||
| 95 | 95 | ||
| 96 | typedef struct TaggedString { | 96 | typedef struct TaggedString { |
| 97 | GCnode head; | 97 | GCnode head; |
| 98 | int constindex; /* hint to reuse constants (= -1 if this is a userdata) */ | ||
| 99 | unsigned long hash; | 98 | unsigned long hash; |
| 99 | int constindex; /* hint to reuse constants (= -1 if this is a userdata) */ | ||
| 100 | union { | 100 | union { |
| 101 | TObject globalval; | 101 | struct { |
| 102 | TObject globalval; | ||
| 103 | long len; /* if this is a string, here is its length */ | ||
| 104 | } s; | ||
| 102 | struct { | 105 | struct { |
| 103 | int tag; | 106 | int tag; |
| 104 | void *v; /* if this is a userdata, here is its value */ | 107 | void *v; /* if this is a userdata, here is its value */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstring.c,v 1.10 1998/01/13 18:06:27 roberto Exp roberto $ | 2 | ** $Id: lstring.c,v 1.11 1998/01/28 16:50:33 roberto Exp roberto $ |
| 3 | ** String table (keeps all strings handled by Lua) | 3 | ** String table (keeps all strings handled by Lua) |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -21,7 +21,8 @@ | |||
| 21 | 21 | ||
| 22 | 22 | ||
| 23 | 23 | ||
| 24 | static TaggedString EMPTY = {{NULL, 2}, 0, 0L, {{LUA_T_NIL, {NULL}}}, {0}}; | 24 | static TaggedString EMPTY = {{NULL, 2}, 0L, 0, |
| 25 | {{{LUA_T_NIL, {NULL}}, 0L}}, {0}}; | ||
| 25 | 26 | ||
| 26 | 27 | ||
| 27 | void luaS_init (void) | 28 | void luaS_init (void) |
| @@ -36,20 +37,14 @@ void luaS_init (void) | |||
| 36 | } | 37 | } |
| 37 | 38 | ||
| 38 | 39 | ||
| 39 | static unsigned long hash (char *s, int tag) | 40 | static unsigned long hash_s (char *s, long l) |
| 40 | { | 41 | { |
| 41 | unsigned long h; | 42 | unsigned long h = 0; |
| 42 | if (tag != LUA_T_STRING) | 43 | while (l--) |
| 43 | h = (unsigned long)s; | 44 | h = ((h<<5)-h)^(unsigned char)*(s++); |
| 44 | else { | ||
| 45 | h = 0; | ||
| 46 | while (*s) | ||
| 47 | h = ((h<<5)-h)^(unsigned char)*(s++); | ||
| 48 | } | ||
| 49 | return h; | 45 | return h; |
| 50 | } | 46 | } |
| 51 | 47 | ||
| 52 | |||
| 53 | static int newsize (stringtable *tb) | 48 | static int newsize (stringtable *tb) |
| 54 | { | 49 | { |
| 55 | int size = tb->size; | 50 | int size = tb->size; |
| @@ -91,34 +86,67 @@ static void grow (stringtable *tb) | |||
| 91 | } | 86 | } |
| 92 | 87 | ||
| 93 | 88 | ||
| 94 | static TaggedString *newone (char *buff, int tag, unsigned long h) | 89 | static TaggedString *newone_s (char *str, long l, unsigned long h) |
| 95 | { | 90 | { |
| 96 | TaggedString *ts; | 91 | TaggedString *ts = (TaggedString *)luaM_malloc(sizeof(TaggedString)+l); |
| 97 | if (tag == LUA_T_STRING) { | 92 | memcpy(ts->str, str, l); |
| 98 | long l = strlen(buff); | 93 | ts->str[l] = 0; /* ending 0 */ |
| 99 | ts = (TaggedString *)luaM_malloc(sizeof(TaggedString)+l); | 94 | ts->u.s.globalval.ttype = LUA_T_NIL; /* initialize global value */ |
| 100 | strcpy(ts->str, buff); | 95 | ts->u.s.len = l; |
| 101 | ts->u.globalval.ttype = LUA_T_NIL; /* initialize global value */ | 96 | ts->constindex = 0; |
| 102 | ts->constindex = 0; | 97 | L->nblocks += gcsizestring(l); |
| 103 | L->nblocks += gcsizestring(l); | ||
| 104 | } | ||
| 105 | else { | ||
| 106 | ts = luaM_new(TaggedString); | ||
| 107 | ts->u.d.v = buff; | ||
| 108 | ts->u.d.tag = tag == LUA_ANYTAG ? 0 : tag; | ||
| 109 | ts->constindex = -1; /* tag -> this is a userdata */ | ||
| 110 | L->nblocks++; | ||
| 111 | } | ||
| 112 | ts->head.marked = 0; | 98 | ts->head.marked = 0; |
| 113 | ts->head.next = (GCnode *)ts; /* signal it is in no list */ | 99 | ts->head.next = (GCnode *)ts; /* signal it is in no list */ |
| 114 | ts->hash = h; | 100 | ts->hash = h; |
| 115 | return ts; | 101 | return ts; |
| 116 | } | 102 | } |
| 117 | 103 | ||
| 118 | static TaggedString *insert (char *buff, int tag, stringtable *tb) | 104 | static TaggedString *newone_u (char *buff, int tag, unsigned long h) |
| 105 | { | ||
| 106 | TaggedString *ts = luaM_new(TaggedString); | ||
| 107 | ts->u.d.v = buff; | ||
| 108 | ts->u.d.tag = (tag == LUA_ANYTAG) ? 0 : tag; | ||
| 109 | ts->constindex = -1; /* tag -> this is a userdata */ | ||
| 110 | L->nblocks++; | ||
| 111 | ts->head.marked = 0; | ||
| 112 | ts->head.next = (GCnode *)ts; /* signal it is in no list */ | ||
| 113 | ts->hash = h; | ||
| 114 | return ts; | ||
| 115 | } | ||
| 116 | |||
| 117 | static TaggedString *insert_s (char *str, long l, stringtable *tb) | ||
| 118 | { | ||
| 119 | TaggedString *ts; | ||
| 120 | unsigned long h = hash_s(str, l); | ||
| 121 | int size = tb->size; | ||
| 122 | int i; | ||
| 123 | int j = -1; | ||
| 124 | if ((long)tb->nuse*3 >= (long)size*2) { | ||
| 125 | grow(tb); | ||
| 126 | size = tb->size; | ||
| 127 | } | ||
| 128 | for (i = h%size; (ts = tb->hash[i]) != NULL; ) { | ||
| 129 | if (ts == &EMPTY) | ||
| 130 | j = i; | ||
| 131 | else if (ts->constindex >= 0 && | ||
| 132 | ts->u.s.len == l && | ||
| 133 | (memcmp(str, ts->str, l) == 0)) | ||
| 134 | return ts; | ||
| 135 | if (++i == size) i=0; | ||
| 136 | } | ||
| 137 | /* not found */ | ||
| 138 | if (j != -1) /* is there an EMPTY space? */ | ||
| 139 | i = j; | ||
| 140 | else | ||
| 141 | tb->nuse++; | ||
| 142 | ts = tb->hash[i] = newone_s(str, l, h); | ||
| 143 | return ts; | ||
| 144 | } | ||
| 145 | |||
| 146 | static TaggedString *insert_u (void *buff, int tag, stringtable *tb) | ||
| 119 | { | 147 | { |
| 120 | TaggedString *ts; | 148 | TaggedString *ts; |
| 121 | unsigned long h = hash(buff, tag); | 149 | unsigned long h = (unsigned long)buff; |
| 122 | int size = tb->size; | 150 | int size = tb->size; |
| 123 | int i; | 151 | int i; |
| 124 | int j = -1; | 152 | int j = -1; |
| @@ -129,9 +157,9 @@ static TaggedString *insert (char *buff, int tag, stringtable *tb) | |||
| 129 | for (i = h%size; (ts = tb->hash[i]) != NULL; ) { | 157 | for (i = h%size; (ts = tb->hash[i]) != NULL; ) { |
| 130 | if (ts == &EMPTY) | 158 | if (ts == &EMPTY) |
| 131 | j = i; | 159 | j = i; |
| 132 | else if ((ts->constindex >= 0) ? /* is a string? */ | 160 | else if (ts->constindex < 0 && /* is a udata? */ |
| 133 | (tag == LUA_T_STRING && (strcmp(buff, ts->str) == 0)) : | 161 | (tag == ts->u.d.tag || tag == LUA_ANYTAG) && |
| 134 | ((tag == ts->u.d.tag || tag == LUA_ANYTAG) && buff == ts->u.d.v)) | 162 | buff == ts->u.d.v) |
| 135 | return ts; | 163 | return ts; |
| 136 | if (++i == size) i=0; | 164 | if (++i == size) i=0; |
| 137 | } | 165 | } |
| @@ -140,18 +168,24 @@ static TaggedString *insert (char *buff, int tag, stringtable *tb) | |||
| 140 | i = j; | 168 | i = j; |
| 141 | else | 169 | else |
| 142 | tb->nuse++; | 170 | tb->nuse++; |
| 143 | ts = tb->hash[i] = newone(buff, tag, h); | 171 | ts = tb->hash[i] = newone_u(buff, tag, h); |
| 144 | return ts; | 172 | return ts; |
| 145 | } | 173 | } |
| 146 | 174 | ||
| 147 | TaggedString *luaS_createudata (void *udata, int tag) | 175 | TaggedString *luaS_createudata (void *udata, int tag) |
| 148 | { | 176 | { |
| 149 | return insert(udata, tag, &L->string_root[(unsigned)udata%NUM_HASHS]); | 177 | return insert_u(udata, tag, &L->string_root[(unsigned)udata%NUM_HASHS]); |
| 178 | } | ||
| 179 | |||
| 180 | TaggedString *luaS_newlstr (char *str, long l) | ||
| 181 | { | ||
| 182 | int i = (l==0)?0:(unsigned char)str[0]; | ||
| 183 | return insert_s(str, l, &L->string_root[i%NUM_HASHS]); | ||
| 150 | } | 184 | } |
| 151 | 185 | ||
| 152 | TaggedString *luaS_new (char *str) | 186 | TaggedString *luaS_new (char *str) |
| 153 | { | 187 | { |
| 154 | return insert(str, LUA_T_STRING, &L->string_root[(unsigned)str[0]%NUM_HASHS]); | 188 | return luaS_newlstr(str, strlen(str)); |
| 155 | } | 189 | } |
| 156 | 190 | ||
| 157 | TaggedString *luaS_newfixedstring (char *str) | 191 | TaggedString *luaS_newfixedstring (char *str) |
| @@ -167,7 +201,7 @@ void luaS_free (TaggedString *l) | |||
| 167 | { | 201 | { |
| 168 | while (l) { | 202 | while (l) { |
| 169 | TaggedString *next = (TaggedString *)l->head.next; | 203 | TaggedString *next = (TaggedString *)l->head.next; |
| 170 | L->nblocks -= (l->constindex == -1) ? 1 : gcsizestring(strlen(l->str)); | 204 | L->nblocks -= (l->constindex == -1) ? 1 : gcsizestring(l->u.s.len); |
| 171 | luaM_free(l); | 205 | luaM_free(l); |
| 172 | l = next; | 206 | l = next; |
| 173 | } | 207 | } |
| @@ -253,7 +287,7 @@ void luaS_freeall (void) | |||
| 253 | 287 | ||
| 254 | void luaS_rawsetglobal (TaggedString *ts, TObject *newval) | 288 | void luaS_rawsetglobal (TaggedString *ts, TObject *newval) |
| 255 | { | 289 | { |
| 256 | ts->u.globalval = *newval; | 290 | ts->u.s.globalval = *newval; |
| 257 | if (ts->head.next == (GCnode *)ts) { /* is not in list? */ | 291 | if (ts->head.next == (GCnode *)ts) { /* is not in list? */ |
| 258 | ts->head.next = L->rootglobal.next; | 292 | ts->head.next = L->rootglobal.next; |
| 259 | L->rootglobal.next = (GCnode *)ts; | 293 | L->rootglobal.next = (GCnode *)ts; |
| @@ -265,7 +299,7 @@ char *luaS_travsymbol (int (*fn)(TObject *)) | |||
| 265 | { | 299 | { |
| 266 | TaggedString *g; | 300 | TaggedString *g; |
| 267 | for (g=(TaggedString *)L->rootglobal.next; g; g=(TaggedString *)g->head.next) | 301 | for (g=(TaggedString *)L->rootglobal.next; g; g=(TaggedString *)g->head.next) |
| 268 | if (fn(&g->u.globalval)) | 302 | if (fn(&g->u.s.globalval)) |
| 269 | return g->str; | 303 | return g->str; |
| 270 | return NULL; | 304 | return NULL; |
| 271 | } | 305 | } |
| @@ -274,6 +308,6 @@ char *luaS_travsymbol (int (*fn)(TObject *)) | |||
| 274 | int luaS_globaldefined (char *name) | 308 | int luaS_globaldefined (char *name) |
| 275 | { | 309 | { |
| 276 | TaggedString *ts = luaS_new(name); | 310 | TaggedString *ts = luaS_new(name); |
| 277 | return ts->u.globalval.ttype != LUA_T_NIL; | 311 | return ts->u.s.globalval.ttype != LUA_T_NIL; |
| 278 | } | 312 | } |
| 279 | 313 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstring.h,v 1.5 1997/11/26 18:53:45 roberto Exp roberto $ | 2 | ** $Id: lstring.h,v 1.6 1997/12/01 20:31:25 roberto Exp roberto $ |
| 3 | ** String table (keep all strings handled by Lua) | 3 | ** String table (keep all strings handled by Lua) |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -15,6 +15,7 @@ void luaS_init (void); | |||
| 15 | TaggedString *luaS_createudata (void *udata, int tag); | 15 | TaggedString *luaS_createudata (void *udata, int tag); |
| 16 | TaggedString *luaS_collector (void); | 16 | TaggedString *luaS_collector (void); |
| 17 | void luaS_free (TaggedString *l); | 17 | void luaS_free (TaggedString *l); |
| 18 | TaggedString *luaS_newlstr (char *str, long l); | ||
| 18 | TaggedString *luaS_new (char *str); | 19 | TaggedString *luaS_new (char *str); |
| 19 | TaggedString *luaS_newfixedstring (char *str); | 20 | TaggedString *luaS_newfixedstring (char *str); |
| 20 | void luaS_rawsetglobal (TaggedString *ts, TObject *newval); | 21 | void luaS_rawsetglobal (TaggedString *ts, TObject *newval); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstrlib.c,v 1.7 1998/01/09 14:57:43 roberto Exp roberto $ | 2 | ** $Id: lstrlib.c,v 1.8 1998/01/27 19:11:36 roberto Exp roberto $ |
| 3 | ** Standard library for strings and pattern-matching | 3 | ** Standard library for strings and pattern-matching |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -19,83 +19,86 @@ | |||
| 19 | static void addnchar (char *s, int n) | 19 | static void addnchar (char *s, int n) |
| 20 | { | 20 | { |
| 21 | char *b = luaL_openspace(n); | 21 | char *b = luaL_openspace(n); |
| 22 | strncpy(b, s, n); | 22 | memcpy(b, s, n); |
| 23 | luaL_addsize(n); | 23 | luaL_addsize(n); |
| 24 | } | 24 | } |
| 25 | 25 | ||
| 26 | 26 | ||
| 27 | static void addstr (char *s) | 27 | static void str_len (void) |
| 28 | { | 28 | { |
| 29 | addnchar(s, strlen(s)); | 29 | long l; |
| 30 | luaL_check_lstr(1, &l); | ||
| 31 | lua_pushnumber(l); | ||
| 30 | } | 32 | } |
| 31 | 33 | ||
| 32 | 34 | ||
| 33 | static void str_len (void) | 35 | static void closeandpush (void) |
| 34 | { | 36 | { |
| 35 | lua_pushnumber(strlen(luaL_check_string(1))); | 37 | lua_pushlstr(luaL_buffer(), luaL_getsize()); |
| 36 | } | 38 | } |
| 37 | 39 | ||
| 38 | 40 | ||
| 39 | static void closeandpush (void) | 41 | static long posrelat (long pos, long len) |
| 40 | { | 42 | { |
| 41 | luaL_addchar(0); | 43 | /* relative string position: negative means back from end */ |
| 42 | lua_pushstring(luaL_buffer()); | 44 | return (pos>=0) ? pos : len+pos+1; |
| 43 | } | 45 | } |
| 44 | 46 | ||
| 45 | 47 | ||
| 46 | static void str_sub (void) | 48 | static void str_sub (void) |
| 47 | { | 49 | { |
| 48 | char *s = luaL_check_string(1); | 50 | long l; |
| 49 | long l = strlen(s); | 51 | char *s = luaL_check_lstr(1, &l); |
| 50 | long start = (long)luaL_check_number(2); | 52 | long start = posrelat(luaL_check_number(2), l); |
| 51 | long end = (long)luaL_opt_number(3, -1); | 53 | long end = posrelat(luaL_opt_number(3, -1), l); |
| 52 | if (start < 0) start = l+start+1; | 54 | if (1 <= start && start <= end && end <= l) |
| 53 | if (end < 0) end = l+end+1; | 55 | lua_pushlstr(s+start-1, end-start+1); |
| 54 | if (1 <= start && start <= end && end <= l) { | ||
| 55 | luaL_resetbuffer(); | ||
| 56 | addnchar(s+start-1, end-start+1); | ||
| 57 | closeandpush(); | ||
| 58 | } | ||
| 59 | else lua_pushstring(""); | 56 | else lua_pushstring(""); |
| 60 | } | 57 | } |
| 61 | 58 | ||
| 62 | 59 | ||
| 63 | static void str_lower (void) | 60 | static void str_lower (void) |
| 64 | { | 61 | { |
| 65 | char *s; | 62 | long l; |
| 63 | int i; | ||
| 64 | char *s = luaL_check_lstr(1, &l); | ||
| 66 | luaL_resetbuffer(); | 65 | luaL_resetbuffer(); |
| 67 | for (s = luaL_check_string(1); *s; s++) | 66 | for (i=0; i<l; i++) |
| 68 | luaL_addchar(tolower((unsigned char)*s)); | 67 | luaL_addchar(tolower((unsigned char)(s[i]))); |
| 69 | closeandpush(); | 68 | closeandpush(); |
| 70 | } | 69 | } |
| 71 | 70 | ||
| 72 | 71 | ||
| 73 | static void str_upper (void) | 72 | static void str_upper (void) |
| 74 | { | 73 | { |
| 75 | char *s; | 74 | long l; |
| 75 | int i; | ||
| 76 | char *s = luaL_check_lstr(1, &l); | ||
| 76 | luaL_resetbuffer(); | 77 | luaL_resetbuffer(); |
| 77 | for (s = luaL_check_string(1); *s; s++) | 78 | for (i=0; i<l; i++) |
| 78 | luaL_addchar(toupper((unsigned char)*s)); | 79 | luaL_addchar(toupper((unsigned char)(s[i]))); |
| 79 | closeandpush(); | 80 | closeandpush(); |
| 80 | } | 81 | } |
| 81 | 82 | ||
| 82 | static void str_rep (void) | 83 | static void str_rep (void) |
| 83 | { | 84 | { |
| 84 | char *s = luaL_check_string(1); | 85 | long l; |
| 86 | char *s = luaL_check_lstr(1, &l); | ||
| 85 | int n = (int)luaL_check_number(2); | 87 | int n = (int)luaL_check_number(2); |
| 86 | luaL_resetbuffer(); | 88 | luaL_resetbuffer(); |
| 87 | while (n-- > 0) | 89 | while (n-- > 0) |
| 88 | addstr(s); | 90 | addnchar(s, l); |
| 89 | closeandpush(); | 91 | closeandpush(); |
| 90 | } | 92 | } |
| 91 | 93 | ||
| 92 | 94 | ||
| 93 | static void str_ascii (void) | 95 | static void str_ascii (void) |
| 94 | { | 96 | { |
| 95 | char *s = luaL_check_string(1); | 97 | long l; |
| 96 | long pos = (long)luaL_opt_number(2, 1) - 1; | 98 | char *s = luaL_check_lstr(1, &l); |
| 97 | luaL_arg_check(0<=pos && pos<strlen(s), 2, "out of range"); | 99 | long pos = posrelat(luaL_opt_number(2, 1), l); |
| 98 | lua_pushnumber((unsigned char)s[pos]); | 100 | luaL_arg_check(0<pos && pos<=l, 2, "out of range"); |
| 101 | lua_pushnumber((unsigned char)s[pos-1]); | ||
| 99 | } | 102 | } |
| 100 | 103 | ||
| 101 | 104 | ||
| @@ -124,14 +127,8 @@ struct Capture { | |||
| 124 | static void push_captures (struct Capture *cap) | 127 | static void push_captures (struct Capture *cap) |
| 125 | { | 128 | { |
| 126 | int i; | 129 | int i; |
| 127 | for (i=0; i<cap->level; i++) { | 130 | for (i=0; i<cap->level; i++) |
| 128 | int l = cap->capture[i].len; | 131 | lua_pushlstr(cap->capture[i].init, cap->capture[i].len); |
| 129 | char *buff = luaL_openspace(l+1); | ||
| 130 | if (l == -1) lua_error("unfinished capture"); | ||
| 131 | strncpy(buff, cap->capture[i].init, l); | ||
| 132 | buff[l] = 0; | ||
| 133 | lua_pushstring(buff); | ||
| 134 | } | ||
| 135 | } | 132 | } |
| 136 | 133 | ||
| 137 | 134 | ||
| @@ -163,7 +160,6 @@ static char *bracket_end (char *p) | |||
| 163 | static int matchclass (int c, int cl) | 160 | static int matchclass (int c, int cl) |
| 164 | { | 161 | { |
| 165 | int res; | 162 | int res; |
| 166 | if (c == 0) return 0; | ||
| 167 | switch (tolower((unsigned char)cl)) { | 163 | switch (tolower((unsigned char)cl)) { |
| 168 | case 'w' : res = isalnum((unsigned char)c); break; | 164 | case 'w' : res = isalnum((unsigned char)c); break; |
| 169 | case 'd' : res = isdigit((unsigned char)c); break; | 165 | case 'd' : res = isdigit((unsigned char)c); break; |
| @@ -184,7 +180,7 @@ int luaI_singlematch (int c, char *p, char **ep) | |||
| 184 | switch (*p) { | 180 | switch (*p) { |
| 185 | case '.': | 181 | case '.': |
| 186 | *ep = p+1; | 182 | *ep = p+1; |
| 187 | return (c != 0); | 183 | return 1; |
| 188 | case '\0': | 184 | case '\0': |
| 189 | *ep = p; | 185 | *ep = p; |
| 190 | return 0; | 186 | return 0; |
| @@ -198,7 +194,6 @@ int luaI_singlematch (int c, char *p, char **ep) | |||
| 198 | int sig = *(p+1) == '^' ? (p++, 0) : 1; | 194 | int sig = *(p+1) == '^' ? (p++, 0) : 1; |
| 199 | if (end == NULL) lua_error("incorrect pattern (missing `]')"); | 195 | if (end == NULL) lua_error("incorrect pattern (missing `]')"); |
| 200 | *ep = end+1; | 196 | *ep = end+1; |
| 201 | if (c == 0) return 0; | ||
| 202 | while (++p < end) { | 197 | while (++p < end) { |
| 203 | if (*p == ESC) { | 198 | if (*p == ESC) { |
| 204 | if (((p+1) < end) && matchclass(c, *++p)) return sig; | 199 | 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) | |||
| 254 | } | 249 | } |
| 255 | else p--; /* and go through */ | 250 | else p--; /* and go through */ |
| 256 | } | 251 | } |
| 257 | return (luaI_singlematch(*s, p, ep) ? s+1 : NULL); | 252 | /* "luaI_singlematch" sets "ep" (so must be called even when *s == 0) */ |
| 253 | return (luaI_singlematch(*s, p, ep) && *s) ? s+1 : NULL; | ||
| 258 | } | 254 | } |
| 259 | 255 | ||
| 260 | 256 | ||
| @@ -322,10 +318,11 @@ static char *match (char *s, char *p, struct Capture *cap) | |||
| 322 | 318 | ||
| 323 | static void str_find (void) | 319 | static void str_find (void) |
| 324 | { | 320 | { |
| 325 | char *s = luaL_check_string(1); | 321 | long l; |
| 322 | char *s = luaL_check_lstr(1, &l); | ||
| 326 | char *p = luaL_check_string(2); | 323 | char *p = luaL_check_string(2); |
| 327 | long init = (long)luaL_opt_number(3, 1) - 1; | 324 | long init = posrelat(luaL_opt_number(3, 1), l) - 1; |
| 328 | luaL_arg_check(0 <= init && init <= strlen(s), 3, "out of range"); | 325 | luaL_arg_check(0 <= init && init <= l, 3, "out of range"); |
| 329 | if (lua_getparam(4) != LUA_NOOBJECT || | 326 | if (lua_getparam(4) != LUA_NOOBJECT || |
| 330 | strpbrk(p, SPECIALS) == NULL) { /* no special caracters? */ | 327 | strpbrk(p, SPECIALS) == NULL) { /* no special caracters? */ |
| 331 | char *s2 = strstr(s+init, p); | 328 | char *s2 = strstr(s+init, p); |
| @@ -381,7 +378,10 @@ static void add_s (lua_Object newp, struct Capture *cap) | |||
| 381 | lua_error(NULL); | 378 | lua_error(NULL); |
| 382 | } | 379 | } |
| 383 | res = lua_getresult(1); | 380 | res = lua_getresult(1); |
| 384 | addstr(lua_isstring(res) ? lua_getstring(res) : ""); | 381 | if (lua_isstring(res)) |
| 382 | addnchar(lua_getstring(res), lua_getstrlen(res)); | ||
| 383 | else | ||
| 384 | addnchar(NULL, 0); | ||
| 385 | lua_endblock(); | 385 | lua_endblock(); |
| 386 | } | 386 | } |
| 387 | else luaL_arg_check(0, 3, "string or function expected"); | 387 | else luaL_arg_check(0, 3, "string or function expected"); |
| @@ -413,7 +413,7 @@ static void str_gsub (void) | |||
| 413 | else break; | 413 | else break; |
| 414 | if (anchor) break; | 414 | if (anchor) break; |
| 415 | } | 415 | } |
| 416 | addstr(src); | 416 | addnchar(src, strlen(src)); |
| 417 | closeandpush(); | 417 | closeandpush(); |
| 418 | lua_pushnumber(n); /* number of substitutions */ | 418 | lua_pushnumber(n); /* number of substitutions */ |
| 419 | } | 419 | } |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lua.h,v 1.14 1998/01/07 16:26:48 roberto Exp roberto $ | 2 | ** $Id: lua.h,v 1.15 1998/02/12 19:23:32 roberto Exp roberto $ |
| 3 | ** Lua - An Extensible Extension Language | 3 | ** Lua - An Extensible Extension Language |
| 4 | ** TeCGraf: Grupo de Tecnologia em Computacao Grafica, PUC-Rio, Brazil | 4 | ** TeCGraf: Grupo de Tecnologia em Computacao Grafica, PUC-Rio, Brazil |
| 5 | ** e-mail: lua@tecgraf.puc-rio.br | 5 | ** e-mail: lua@tecgraf.puc-rio.br |
| @@ -90,12 +90,14 @@ int lua_isfunction (lua_Object object); | |||
| 90 | 90 | ||
| 91 | double lua_getnumber (lua_Object object); | 91 | double lua_getnumber (lua_Object object); |
| 92 | char *lua_getstring (lua_Object object); | 92 | char *lua_getstring (lua_Object object); |
| 93 | long lua_getstrlen (lua_Object object); | ||
| 93 | lua_CFunction lua_getcfunction (lua_Object object); | 94 | lua_CFunction lua_getcfunction (lua_Object object); |
| 94 | void *lua_getuserdata (lua_Object object); | 95 | void *lua_getuserdata (lua_Object object); |
| 95 | 96 | ||
| 96 | 97 | ||
| 97 | void lua_pushnil (void); | 98 | void lua_pushnil (void); |
| 98 | void lua_pushnumber (double n); | 99 | void lua_pushnumber (double n); |
| 100 | void lua_pushlstr (char *s, long len); | ||
| 99 | void lua_pushstring (char *s); | 101 | void lua_pushstring (char *s); |
| 100 | void lua_pushCclosure (lua_CFunction fn, int n); | 102 | void lua_pushCclosure (lua_CFunction fn, int n); |
| 101 | void lua_pushusertag (void *u, int tag); | 103 | void lua_pushusertag (void *u, int tag); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lvm.c,v 1.22 1998/01/12 13:35:37 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 1.23 1998/01/14 13:49:15 roberto Exp roberto $ |
| 3 | ** Lua virtual machine | 3 | ** Lua virtual machine |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -37,13 +37,14 @@ | |||
| 37 | 37 | ||
| 38 | 38 | ||
| 39 | 39 | ||
| 40 | static TaggedString *strconc (char *l, char *r) | 40 | static TaggedString *strconc (TaggedString *l, TaggedString *r) |
| 41 | { | 41 | { |
| 42 | size_t nl = strlen(l); | 42 | size_t nl = l->u.s.len; |
| 43 | char *buffer = luaL_openspace(nl+strlen(r)+1); | 43 | size_t nr = r->u.s.len; |
| 44 | strcpy(buffer, l); | 44 | char *buffer = luaL_openspace(nl+nr+1); |
| 45 | strcpy(buffer+nl, r); | 45 | memcpy(buffer, l->str, nl); |
| 46 | return luaS_new(buffer); | 46 | memcpy(buffer+nl, r->str, nr); |
| 47 | return luaS_newlstr(buffer, nl+nr); | ||
| 47 | } | 48 | } |
| 48 | 49 | ||
| 49 | 50 | ||
| @@ -167,7 +168,7 @@ void luaV_settable (TObject *t, int mode) | |||
| 167 | void luaV_getglobal (TaggedString *ts) | 168 | void luaV_getglobal (TaggedString *ts) |
| 168 | { | 169 | { |
| 169 | /* WARNING: caller must assure stack space */ | 170 | /* WARNING: caller must assure stack space */ |
| 170 | TObject *value = &ts->u.globalval; | 171 | TObject *value = &ts->u.s.globalval; |
| 171 | TObject *im = luaT_getimbyObj(value, IM_GETGLOBAL); | 172 | TObject *im = luaT_getimbyObj(value, IM_GETGLOBAL); |
| 172 | if (ttype(im) == LUA_T_NIL) { /* default behavior */ | 173 | if (ttype(im) == LUA_T_NIL) { /* default behavior */ |
| 173 | *L->stack.top++ = *value; | 174 | *L->stack.top++ = *value; |
| @@ -185,7 +186,7 @@ void luaV_getglobal (TaggedString *ts) | |||
| 185 | 186 | ||
| 186 | void luaV_setglobal (TaggedString *ts) | 187 | void luaV_setglobal (TaggedString *ts) |
| 187 | { | 188 | { |
| 188 | TObject *oldvalue = &ts->u.globalval; | 189 | TObject *oldvalue = &ts->u.s.globalval; |
| 189 | TObject *im = luaT_getimbyObj(oldvalue, IM_SETGLOBAL); | 190 | TObject *im = luaT_getimbyObj(oldvalue, IM_SETGLOBAL); |
| 190 | if (ttype(im) == LUA_T_NIL) /* default behavior */ | 191 | if (ttype(im) == LUA_T_NIL) /* default behavior */ |
| 191 | luaS_rawsetglobal(ts, --L->stack.top); | 192 | luaS_rawsetglobal(ts, --L->stack.top); |
| @@ -224,6 +225,23 @@ static void call_arith (IMS event) | |||
| 224 | } | 225 | } |
| 225 | 226 | ||
| 226 | 227 | ||
| 228 | static int strcomp (char *l, long ll, char *r, long lr) | ||
| 229 | { | ||
| 230 | for (;;) { | ||
| 231 | long temp = strcoll(l, r); | ||
| 232 | if (temp != 0) return temp; | ||
| 233 | /* strings are equal up to a '\0' */ | ||
| 234 | temp = strlen(l); /* index of first '\0' in both strings */ | ||
| 235 | if (temp == ll) /* l is finished? */ | ||
| 236 | return (temp == lr) ? 0 : -1; /* l is equal or smaller than r */ | ||
| 237 | else if (temp == lr) /* r is finished? */ | ||
| 238 | return 1; /* l is greater than r (because l is not finished) */ | ||
| 239 | /* both strings longer than temp; go on comparing (after the '\0') */ | ||
| 240 | temp++; | ||
| 241 | l += temp; ll -= temp; r += temp; lr -= temp; | ||
| 242 | } | ||
| 243 | } | ||
| 244 | |||
| 227 | static void comparison (lua_Type ttype_less, lua_Type ttype_equal, | 245 | static void comparison (lua_Type ttype_less, lua_Type ttype_equal, |
| 228 | lua_Type ttype_great, IMS op) | 246 | lua_Type ttype_great, IMS op) |
| 229 | { | 247 | { |
| @@ -234,7 +252,8 @@ static void comparison (lua_Type ttype_less, lua_Type ttype_equal, | |||
| 234 | if (ttype(l) == LUA_T_NUMBER && ttype(r) == LUA_T_NUMBER) | 252 | if (ttype(l) == LUA_T_NUMBER && ttype(r) == LUA_T_NUMBER) |
| 235 | result = (nvalue(l) < nvalue(r)) ? -1 : (nvalue(l) == nvalue(r)) ? 0 : 1; | 253 | result = (nvalue(l) < nvalue(r)) ? -1 : (nvalue(l) == nvalue(r)) ? 0 : 1; |
| 236 | else if (ttype(l) == LUA_T_STRING && ttype(r) == LUA_T_STRING) | 254 | else if (ttype(l) == LUA_T_STRING && ttype(r) == LUA_T_STRING) |
| 237 | result = strcoll(svalue(l), svalue(r)); | 255 | result = strcomp(svalue(l), tsvalue(l)->u.s.len, |
| 256 | svalue(r), tsvalue(r)->u.s.len); | ||
| 238 | else { | 257 | else { |
| 239 | call_binTM(op, "unexpected type in comparison"); | 258 | call_binTM(op, "unexpected type in comparison"); |
| 240 | return; | 259 | return; |
| @@ -582,7 +601,7 @@ StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base) | |||
| 582 | if (tostring(l) || tostring(r)) | 601 | if (tostring(l) || tostring(r)) |
| 583 | call_binTM(IM_CONCAT, "unexpected type for concatenation"); | 602 | call_binTM(IM_CONCAT, "unexpected type for concatenation"); |
| 584 | else { | 603 | else { |
| 585 | tsvalue(l) = strconc(svalue(l), svalue(r)); | 604 | tsvalue(l) = strconc(tsvalue(l), tsvalue(r)); |
| 586 | --S->top; | 605 | --S->top; |
| 587 | } | 606 | } |
| 588 | luaC_checkGC(); | 607 | luaC_checkGC(); |
