diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1998-03-06 13:54:42 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1998-03-06 13:54:42 -0300 |
commit | 88a2023c3285c4514519158fba90e644fc6ffca3 (patch) | |
tree | da6611257545c486ff856dd48d66d94e056f3d66 /lvm.c | |
parent | 5ef1989c4b05aff8362a7ea6ba62aad76d4a040d (diff) | |
download | lua-88a2023c3285c4514519158fba90e644fc6ffca3.tar.gz lua-88a2023c3285c4514519158fba90e644fc6ffca3.tar.bz2 lua-88a2023c3285c4514519158fba90e644fc6ffca3.zip |
support for strings with '\0'
Diffstat (limited to 'lvm.c')
-rw-r--r-- | lvm.c | 41 |
1 files changed, 30 insertions, 11 deletions
@@ -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(); |