Przeglądaj źródła

Several fixes found when translating lua 5.1 tests (http://www.inf.puc-rio.br/%7Eroberto/lua/lua5.1-tests.tar.gz)

mingodad 8 lat temu
rodzic
commit
c74277f2c2

+ 34 - 17
SquiLu/squirrel/lua-regex.c

@@ -50,17 +50,35 @@ static ptrdiff_t posrelat (ptrdiff_t pos, size_t len) {
   return (pos >= 0) ? pos : 0;
 }
 
-static int check_capture (LuaMatchState *ms, int *l_out) {
-  int l;
-  *l_out -= '1';
-  l = *l_out;
-  if (l < 0 || l >= ms->level || ms->capture[l].len == CAP_UNFINISHED){
+static int check_capture_all_closed (LuaMatchState *ms) {
+  int i;
+  for(i=0; i<ms->level; ++i){
+      if(ms->capture[i].len == CAP_UNFINISHED){
+          ms->error = "unfinished capture";
+          return 0;
+      }
+  }
+  return 1;
+}
+
+static int check_capture_is_closed (LuaMatchState *ms, int l) {
+  if (l < 0 || l >= ms->level){
       ms->error = "invalid capture index";
       return 0;
   }
+  if (ms->capture[l].len == CAP_UNFINISHED){
+      ms->error = "unfinished capture";
+      return 0;
+  }
   return 1;
 }
 
+static int check_capture (LuaMatchState *ms, int *l_out) {
+  int l;
+  *l_out -= '1';
+  l = *l_out;
+  return check_capture_is_closed(ms, l);
+}
 static int capture_to_close (LuaMatchState *ms, int *level_out) {
   int level = ms->level;
   for (level--; level>=0; level--)
@@ -392,7 +410,7 @@ do_again:
   /* explicit request or no special characters? */
   if (find && (raw_find || nospecials(p, lp))) {
     /* do a plain search */
-    const char *s2 = lmemfind(s + init, ls - init + 1, p, lp);
+    const char *s2 = lmemfind(s + init, ls - init, p, lp);
     if (s2) {
       ms->start_pos = ((int)(s2 - s));
       result = ms->end_pos = ms->start_pos+lp;
@@ -411,7 +429,7 @@ do_again:
       ms->level = 0;
       if ((res=match(ms, s1, p)) != NULL) {
           ms->start_pos = s1-s;
-          result = ms->end_pos = res-s-1;
+          result = ms->end_pos = res-s;
           goto eofunc;
       }
     } while (s1++ < ms->src_end && !anchor);
@@ -420,15 +438,9 @@ do_again:
 eofunc:
 
   if(result >= 0){
-      int i;
-      for(i=0; i<ms->level; ++i){
-          if(ms->capture[i].len == CAP_UNFINISHED){
-              ms->error = "unfinished capture";
-              return 0;
-          }
-      }
+      if(!check_capture_all_closed(ms)) return 0;
       if(fp && (*fp)(ms, udata, 0)) {
-          init = result+1;
+          init = result;
           if (init < ls) goto do_again;
       }
   }
@@ -565,6 +577,7 @@ lua_char_buffer_st *lua_str_gsub (const char *src, ptrdiff_t srcl, const char *p
     p++; lp--;  /* skip anchor character */
   }
   ms.error = 0;
+  ms.start_pos = ms.end_pos = 0;
   ms.src_init = src;
   ms.src_end = src+srcl;
   ms.p_end = p + lp;
@@ -572,18 +585,22 @@ lua_char_buffer_st *lua_str_gsub (const char *src, ptrdiff_t srcl, const char *p
     const char *e;
     ms.level = 0;
     e = match(&ms, src, p);
-    if(ms.error) goto free_and_null;
+    if(ms.error || !check_capture_all_closed(&ms)) goto free_and_null;
     if (e) {
       n++;
       if(fp){
+          ms.end_pos = e-ms.src_init;
           if(!(*fp)(&ms, udata, &b)) goto free_and_null;
       }
       else if(!add_value(&ms, &b, src, e, tr, ltr)) goto free_and_null;
     }
-    if (e && e>src) /* non empty match? */
+    if (e && e>src){ /* non empty match? */
+      ms.start_pos = e-ms.src_init;
       src = e;  /* skip it */
+    }
     else if (src < ms.src_end){
       if(!char_buffer_add_char(&ms, &b, *src++)) goto free_and_null;
+      ++ms.start_pos;
     }
     else break;
     if (anchor) break;

+ 32 - 12
SquiLu/squirrel/sqbaselib.cpp

@@ -1156,20 +1156,25 @@ static SQRESULT array_concat0 (HSQUIRRELVM v, int allowAll) {
     SQ_FUNC_VARS(v);
     SQObjectPtr &arobj = stack_get(v,1);
     SQObjectPtrVec &aryvec = _array(arobj)->_values;
-    SQInteger last = aryvec.size();
+    SQInteger last = aryvec.size()-1;
     if(last == 0){
         sq_pushstring(v, _SC(""), 0);
         return 1;
     }
     SQ_OPT_STRING(v, 2, sep, _SC(""));
-    SQ_OPT_INTEGER(v, 3, i, 0);
+    SQ_OPT_INTEGER(v, 3, opt_first, 0);
     SQ_OPT_INTEGER(v, 4, opt_last, last);
 
-  last = opt_last < last ? opt_last : last;
-  opt_last = last -1;
+  opt_last = opt_last < last ? opt_last : last;
+
+  if(opt_first > opt_last)
+  {
+      sq_pushstring(v, "", 0);
+      return 1;
+  }
   SQBlob blob(0, 8192);
 
-  for (; i < last; ++i) {
+  for (int i=opt_first; i <= opt_last; ++i) {
       SQObjectPtr str, &o = aryvec[i];
       switch(sq_type(o)){
           case OT_STRING:
@@ -1200,8 +1205,8 @@ static SQRESULT array_concat0 (HSQUIRRELVM v, int allowAll) {
 		value = _stringval(str);
 		value_size = _string(str)->_len;
       }
+      if(i > opt_first && sep_size) blob.Write((void*)sep, sep_size);
       blob.Write((void*)value, value_size);
-      if(i != opt_last && sep_size) blob.Write((void*)sep, sep_size);
   }
   sq_pushstring(v, (SQChar*)blob.GetBuf(), blob.Len());
   return 1;
@@ -1381,6 +1386,7 @@ static int process_string_gsub(LuaMatchState *ms, void *udata, lua_char_buffer_s
     SQInteger top = sq_gettop(v);
     SQInteger result = 1;
     switch(rtype){
+        case OT_NATIVECLOSURE:
         case OT_CLOSURE:{
             sq_push(v, 3); //push the function
             sq_pushroottable(v); //this
@@ -1388,6 +1394,11 @@ static int process_string_gsub(LuaMatchState *ms, void *udata, lua_char_buffer_s
             for(; i < ms->level; ++i){
                 push_match_capture(v, i, ms);
             }
+            if(i==0) //no captures push whole match
+            {
+                sq_pushstring(v, ms->src_init + ms->start_pos, ms->end_pos-ms->start_pos);
+                ++i;
+            }
             int rc = sq_call(v, i+1, SQTrue, SQTrue);
             if(rc < 0) {
                 ms->error = sq_getlasterror_str(v);
@@ -1425,6 +1436,13 @@ static int process_string_gsub(LuaMatchState *ms, void *udata, lua_char_buffer_s
                     }
                     sq_pop(v, 1); //remove value
                 }
+                else
+                {
+                    if(!char_buffer_add_str(ms, b, ms->capture[i].init, ms->capture[i].len)) {
+                        result = 0;
+                        break;
+                    }
+                }
             }
         }
     }
@@ -1434,7 +1452,7 @@ static int process_string_gsub(LuaMatchState *ms, void *udata, lua_char_buffer_s
 
 static SQRESULT string_gsub(HSQUIRRELVM v)
 {
-    const char *error_ptr;
+    const char *error_ptr = NULL;
     SQ_FUNC_VARS(v);
     SQ_GET_STRING(v, 1, src);
     SQ_GET_STRING(v, 2, pattern);
@@ -1460,14 +1478,16 @@ static SQRESULT string_gsub(HSQUIRRELVM v)
     {
         switch(rtype){
             case OT_CLOSURE:
+            case OT_NATIVECLOSURE:
             case OT_ARRAY:
             case OT_TABLE:{
                 lua_char_buffer_st *buf = lua_str_gsub (src, src_size, pattern, pattern_size,
                               0, 0, max_sub, &error_ptr, process_string_gsub, v);
                 if(buf){
-                    sq_pushstring(v, buf->buf, buf->used);
+                    if(buf->used) sq_pushstring(v, buf->buf, buf->used);
+                    else sq_push(v, 1); //nothing matches so return the original
                     free(buf);
-                    return 1;
+                    if(!error_ptr) return 1;
                 }
                 return sq_throwerror(v,error_ptr);
             }
@@ -1491,7 +1511,7 @@ static SQRESULT process_string_gmatch_find(LuaMatchState *ms, void *udata, lua_c
         push_match_capture(v, i, ms);
     }
     if(!isFind && i == 0){
-        sq_pushstring(v, ms->src_init + ms->start_pos, ms->end_pos-ms->start_pos+1);
+        sq_pushstring(v, ms->src_init + ms->start_pos, ms->end_pos-ms->start_pos);
         i=1;
     }
     int rc = sq_call(v, i+1 + (isFind ? 2 : 0), SQTrue, SQTrue);
@@ -1532,7 +1552,7 @@ SQRESULT string_gmatch_base(HSQUIRRELVM v, int isGmatch, const SQChar *src, SQIn
             src_size = calc_new_size_by_max_len(start_pos, max_len, src_size);
         }
         //if (start_pos < 0) start_pos = 0;
-        if(rtype == OT_CLOSURE){
+        if((rtype == OT_CLOSURE) || (rtype == OT_NATIVECLOSURE)){
             _rc_ = lua_str_match(&ms, src, max_len ? start_pos + max_len : src_size,
                     pattern, pattern_size, start_pos, 0, process_string_gmatch, v);
             if(ms.error) return sq_throwerror(v, ms.error);
@@ -1608,7 +1628,7 @@ SQRESULT string_find_lua(HSQUIRRELVM v, const SQChar *src, SQInteger src_size)
         sq_pushinteger(v, rc);
         return 1;
     }
-    if(rtype == OT_CLOSURE){
+    if((rtype == OT_CLOSURE) || (rtype == OT_NATIVECLOSURE)){
         LuaMatchState ms;
         memset(&ms, 0, sizeof(ms));
         int rc = lua_str_find(&ms, src, src_size, pattern, pattern_size,

+ 1 - 5
SquiLu/squirrel/sqcompiler.cpp

@@ -1993,8 +1993,8 @@ function_params_decl:
 		Lex(); Expect(_SC('(')); CommaExpr(true); Expect(_SC(')'));
 		_fs->AddInstruction(_OP_JZ, _fs->PopTarget());
 		SQInteger jnepos = _fs->GetCurrentPos();
-		BEGIN_SCOPE();
 
+        IfBlock();
         //there is a situation where the if statement has a statement enclosed by {}
         //and after the closing "}" there is no newline or semicolom
         //it's a valid construction but the compiler was complaining about it
@@ -2005,11 +2005,7 @@ if(color == "yellow"){
 	print(color);
 } print("Waht color is it ?");
 */
-		Statement();
-		//
-		if(_token != _SC('}') && _token != TK_ELSE && _token != TK_IDENTIFIER) OptionalSemicolon();
 
-		END_SCOPE();
 		SQInteger endifblock = _fs->GetCurrentPos();
 		if(_token == TK_ELSE){
 			haselse = true;

+ 2 - 0
SquiLu/squirrel/sqvm.cpp

@@ -391,6 +391,7 @@ bool SQVM::ToString(const SQObjectPtr &o,SQObjectPtr &res)
 	return true;
 }
 
+#define SQ_MAX_STR_SIZE	(((size_t)(512*1024*1024)))
 
 bool SQVM::StringCat(const SQObjectPtr &str,const SQObjectPtr &obj,SQObjectPtr &dest)
 {
@@ -398,6 +399,7 @@ bool SQVM::StringCat(const SQObjectPtr &str,const SQObjectPtr &obj,SQObjectPtr &
 	if(!ToString(str, a)) return false;
 	if(!ToString(obj, b)) return false;
 	SQInteger l = _string(a)->_len , ol = _string(b)->_len;
+	//if (l >= SQ_MAX_STR_SIZE - ol) Raise_Error(_SC("string length overflow"));
 	SQChar *s = _sp(sq_rsl(l + ol + 1));
 	memcpy(s, _stringval(a), sq_rsl(l));
 	memcpy(s + l, _stringval(b), sq_rsl(ol));