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(); |
