compiler/pass15; ide/debugger: Fixed evaluation of class("abc" + 1) and indexing...
authorJerome St-Louis <jerome@ecere.com>
Tue, 6 May 2014 11:50:36 +0000 (07:50 -0400)
committerJerome St-Louis <jerome@ecere.com>
Tue, 6 May 2014 11:50:36 +0000 (07:50 -0400)
- Also fixed unescaping not to include a \ on invalid escape characters

compiler/bootstrap/libec/bootstrap/pass15.c
compiler/libec/src/pass15.ec
ide/src/debugger/Debugger.ec
ide/src/debugger/debugTools.ec

index 63c97e4..decce6e 100644 (file)
@@ -10457,8 +10457,10 @@ break;
 case '\"':
 output[d] = '\"';
 break;
+case '\'':
+output[d] = '\'';
+break;
 default:
-output[d++] = '\\';
 output[d] = ch;
 }
 d++;
@@ -10480,6 +10482,76 @@ output[d++] = ch;
 output[d] = '\0';
 }
 
+int UnescapeString(char * d, char * s, int len)
+{
+int j = 0, k = 0;
+char ch;
+
+while(j < len && (ch = s[j]))
+{
+switch(ch)
+{
+case '\\':
+switch((ch = s[++j]))
+{
+case 'n':
+d[k] = '\n';
+break;
+case 't':
+d[k] = '\t';
+break;
+case 'a':
+d[k] = '\a';
+break;
+case 'b':
+d[k] = '\b';
+break;
+case 'f':
+d[k] = '\f';
+break;
+case 'r':
+d[k] = '\r';
+break;
+case 'v':
+d[k] = '\v';
+break;
+case '\\':
+d[k] = '\\';
+break;
+case '\"':
+d[k] = '\"';
+break;
+case '\'':
+d[k] = '\'';
+break;
+default:
+d[k] = '\\';
+d[k] = ch;
+}
+break;
+default:
+d[k] = ch;
+}
+j++, k++;
+}
+d[k] = '\0';
+return k;
+}
+
+char * OffsetEscapedString(char * s, int len, int offset)
+{
+char ch;
+int j = 0, k = 0;
+
+while(j < len && k < offset && (ch = s[j]))
+{
+if(ch == '\\')
+++j;
+j++, k++;
+}
+return (k == offset) ? s + j : (((void *)0));
+}
+
 extern long long __ecereNameSpace__ecere__com___strtoi64(char *  string, char * *  endString, int base);
 
 extern uint64 __ecereNameSpace__ecere__com___strtoui64(char *  string, char * *  endString, int base);
@@ -11533,7 +11605,50 @@ struct Operand op2 =
 };
 
 if(exp->op.exp2)
+{
+struct Expression * e = exp->op.exp2;
+
+while(((e->type == 5 || e->type == 32 || e->type == 23) && e->list) || e->type == 11)
+{
+if(e->type == 5 || e->type == 32 || e->type == 23)
+{
+if(e->type == 23)
+e = (*((struct Statement *)(*e->compound->compound.statements).last)->expressions).last;
+else
+e = (*e->list).last;
+}
+else if(e->type == 11)
+e = e->cast.exp;
+}
+if(exp->op.op == 261 && e && e->expType)
+{
+if(e->type == 3 && e->string)
+{
+char * string = e->string;
+int len = strlen(string);
+char * tmp = __ecereNameSpace__ecere__com__eSystem_New(sizeof(char) * (len - 2 + 1));
+
+len = UnescapeString(tmp, string + 1, len - 2);
+(__ecereNameSpace__ecere__com__eSystem_Delete(tmp), tmp = 0);
+FreeExpContents(exp);
+exp->type = 2;
+exp->constant = PrintUInt(len + 1);
+}
+else
+{
+struct Type * type = e->expType;
+
+type->refCount++;
+FreeExpContents(exp);
+exp->type = 2;
+exp->constant = PrintUInt(ComputeTypeSize(type));
+FreeType(type);
+}
+break;
+}
+else
 ComputeExpression(exp->op.exp2);
+}
 if(exp->op.exp1)
 {
 ComputeExpression(exp->op.exp1);
@@ -18134,6 +18249,8 @@ __ecereNameSpace__ecere__com__eSystem_RegisterFunction("ModuleVisibility", "bool
 __ecereNameSpace__ecere__com__eSystem_RegisterFunction("MatchWithEnums_Module", "bool MatchWithEnums_Module(ecere::com::Module mainModule, Expression sourceExp, Type dest, char * string, ecere::sys::OldList conversions)", MatchWithEnums_Module, module, 2);
 __ecereNameSpace__ecere__com__eSystem_RegisterFunction("MatchTypeExpression", "bool MatchTypeExpression(Expression sourceExp, Type dest, ecere::sys::OldList conversions, bool skipUnitBla)", MatchTypeExpression, module, 2);
 __ecereNameSpace__ecere__com__eSystem_RegisterFunction("ReadString", "void ReadString(char * output, char * string)", ReadString, module, 1);
+__ecereNameSpace__ecere__com__eSystem_RegisterFunction("UnescapeString", "int UnescapeString(char * d, char * s, int len)", UnescapeString, module, 1);
+__ecereNameSpace__ecere__com__eSystem_RegisterFunction("OffsetEscapedString", "char * OffsetEscapedString(char * s, int len, int offset)", OffsetEscapedString, module, 1);
 __ecereNameSpace__ecere__com__eSystem_RegisterFunction("GetOperand", "Operand GetOperand(Expression exp)", GetOperand, module, 1);
 __ecereNameSpace__ecere__com__eSystem_RegisterFunction("PopulateInstance", "void PopulateInstance(Instantiation inst)", PopulateInstance, module, 1);
 __ecereNameSpace__ecere__com__eSystem_RegisterFunction("ComputeInstantiation", "void ComputeInstantiation(Expression exp)", ComputeInstantiation, module, 1);
index e205dec..dce3a10 100644 (file)
@@ -4154,8 +4154,8 @@ public void ReadString(char * output,  char * string)
             case 'v': output[d] = '\v'; break;
             case '\\': output[d] = '\\'; break;
             case '\"': output[d] = '\"'; break;
-            default: output[d++] = '\\'; output[d] = ch;
-            //default: output[d] = ch;
+            case '\'': output[d] = '\''; break;
+            default: output[d] = ch;
          }
          d++;
          escaped = false;
@@ -4176,6 +4176,55 @@ public void ReadString(char * output,  char * string)
    output[d] = '\0';
 }
 
+// String Unescape Copy
+
+// TOFIX: THIS DOESN'T HANDLE NUMERIC ESCAPE CODES (OCTAL/HEXADECIMAL...)?
+// This is the same as ReadString above (which also misses numeric escape codes) except it doesn't handle external quotes
+public int UnescapeString(char * d, char * s, int len)
+{
+   int j = 0, k = 0;
+   char ch;
+   while(j < len && (ch = s[j]))
+   {
+      switch(ch)
+      {
+         case '\\':
+            switch((ch = s[++j]))
+            {
+               case 'n': d[k] = '\n'; break;
+               case 't': d[k] = '\t'; break;
+               case 'a': d[k] = '\a'; break;
+               case 'b': d[k] = '\b'; break;
+               case 'f': d[k] = '\f'; break;
+               case 'r': d[k] = '\r'; break;
+               case 'v': d[k] = '\v'; break;
+               case '\\': d[k] = '\\'; break;
+               case '\"': d[k] = '\"'; break;
+               case '\'': d[k] = '\''; break;
+               default: d[k] = '\\'; d[k] = ch;
+            }
+            break;
+         default:
+            d[k] = ch;
+      }
+      j++, k++;
+   }
+   d[k] = '\0';
+   return k;
+}
+
+public char * OffsetEscapedString(char * s, int len, int offset)
+{
+   char ch;
+   int j = 0, k = 0;
+   while(j < len && k < offset && (ch = s[j]))
+   {
+      if(ch == '\\') ++j;
+      j++, k++;
+   }
+   return (k == offset) ? s + j : null;
+}
+
 public Operand GetOperand(Expression exp)
 {
    Operand op { };
@@ -5152,7 +5201,48 @@ void ComputeExpression(Expression exp)
 
          // We don't care about operations with only exp2 (INC_OP, DEC_OP...)
          if(exp.op.exp2)
-            ComputeExpression(exp.op.exp2);
+         {
+            Expression e = exp.op.exp2;
+
+            while(((e.type == bracketsExp || e.type == extensionExpressionExp || e.type == extensionCompoundExp) && e.list) || e.type == castExp)
+            {
+               if(e.type == bracketsExp || e.type == extensionExpressionExp || e.type == extensionCompoundExp)
+               {
+                  if(e.type == extensionCompoundExp)
+                     e = ((Statement)e.compound.compound.statements->last).expressions->last;
+                  else
+                     e = e.list->last;
+               }
+               else if(e.type == castExp)
+                  e = e.cast.exp;
+            }
+            if(exp.op.op == TokenType::sizeOf && e && e.expType)
+            {
+               if(e.type == stringExp && e.string)
+               {
+                  char * string = e.string;
+                  int len = strlen(string);
+                  char * tmp = new char[len-2+1];
+                  len = UnescapeString(tmp, string + 1, len - 2);
+                  delete tmp;
+                  FreeExpContents(exp);
+                  exp.type = constantExp;
+                  exp.constant = PrintUInt(len + 1);
+               }
+               else
+               {
+                  Type type = e.expType;
+                  type.refCount++;
+                  FreeExpContents(exp);
+                  exp.type = constantExp;
+                  exp.constant = PrintUInt(ComputeTypeSize(type));
+                  FreeType(type);
+               }
+               break;
+            }
+            else
+               ComputeExpression(exp.op.exp2);
+         }
          if(exp.op.exp1)
          {
             ComputeExpression(exp.op.exp1);
index 7712fc2..7f80104 100644 (file)
@@ -195,8 +195,9 @@ static void strescpy(char * d, char * s)
 
 static char * CopyUnescapedSystemPath(char * p)
 {
-   char * d = new char[strlen(p) + 1];
-   struscpy(d, p);
+   int len = strlen(p);
+   char * d = new char[len + 1];
+   UnescapeString(d, p, len);
 #if defined(__WIN32__)
    ChangeCh(d, '/', '\\');
 #endif
@@ -205,8 +206,9 @@ static char * CopyUnescapedSystemPath(char * p)
 
 static char * CopyUnescapedUnixPath(char * p)
 {
-   char * d = new char[strlen(p) + 1];
-   struscpy(d, p);
+   int len = strlen(p);
+   char * d = new char[len + 1];
+   UnescapeString(d, p, len);
 #if defined(__WIN32__)
    ChangeCh(d, '\\', '/');
 #endif
@@ -215,47 +217,12 @@ static char * CopyUnescapedUnixPath(char * p)
 
 static char * CopyUnescapedString(char * s)
 {
-   char * d = new char[strlen(s) + 1];
-   struscpy(d, s);
+   int len = strlen(s);
+   char * d = new char[len + 1];
+   UnescapeString(d, s, len);
    return d;
 }
 
-// String Unescape Copy
-
-// TOFIX: THIS DOESN'T HANDLE NUMERIC ESCAPE CODES (OCTAL/HEXADECIMAL...)?
-// Seems very similar to ReadString in pass15.ec (which also misses numeric escape codes :) )
-
-static void struscpy(char * d, char * s)
-{
-   int j = 0, k = 0;
-   char ch;
-   while((ch = s[j]))
-   {
-      switch(ch)
-      {
-         case '\\':
-            switch(s[++j])
-            {
-               case 'n': d[k] = '\n'; break;
-               case 't': d[k] = '\t'; break;
-               case 'a': d[k] = '\a'; break;
-               case 'b': d[k] = '\b'; break;
-               case 'f': d[k] = '\f'; break;
-               case 'r': d[k] = '\r'; break;
-               case 'v': d[k] = '\v'; break;
-               case '\\': d[k] = '\\'; break;
-               case '\"': d[k] = '\"'; break;
-               default: d[k] = '\\'; d[++k] = s[j];
-            }
-            break;
-         default:
-            d[k] = s[j];
-      }
-      j++, k++;
-   }
-   d[k] = '\0';
-}
-
 static char * StripBrackets(char * string)
 {
    int length = strlen(string);
@@ -2939,7 +2906,7 @@ class Debugger
                      snprintf(watchmsg, sizeof(watchmsg), $"Memory can't be read at %s", /*(exp.type == constantExp) ? */exp.constant /*: null*/);
                      break;
                   case dereferenceErrorExp:
-                     snprintf(watchmsg, sizeof(watchmsg), $"Dereferencing error evaluating for \"%s\"", wh.expression);
+                     snprintf(watchmsg, sizeof(watchmsg), $"Dereferencing error evaluating \"%s\"", wh.expression);
                      break;
                   case noDebuggerErrorExp:
                      snprintf(watchmsg, sizeof(watchmsg), $"Debugger required for symbol evaluation in \"%s\"", wh.expression);
index d97f7e4..5a8260c 100644 (file)
@@ -398,15 +398,42 @@ void DebugComputeExpression(Expression exp)
          // We don't care about operations with only exp2 (INC_OP, DEC_OP...)
          if(exp.op.exp2)
          {
-            PrintLn((int)exp.op.op);
-            if(exp.op.op == TokenType::sizeOf && exp.op.exp2.expType)
+            Expression e = exp.op.exp2;
+
+            while(((e.type == bracketsExp || e.type == extensionExpressionExp || e.type == extensionCompoundExp) && e.list) || e.type == castExp)
             {
-               Type type = exp.op.exp2.expType;
-               type.refCount++;
-               FreeExpContents(exp);
-               exp.type = constantExp;
-               exp.constant = PrintUInt(ComputeTypeSize(type));
-               FreeType(type);
+               if(e.type == bracketsExp || e.type == extensionExpressionExp || e.type == extensionCompoundExp)
+               {
+                  if(e.type == extensionCompoundExp)
+                     e = ((Statement)e.compound.compound.statements->last).expressions->last;
+                  else
+                     e = e.list->last;
+               }
+               else if(e.type == castExp)
+                  e = e.cast.exp;
+            }
+            if(exp.op.op == TokenType::sizeOf && e && e.expType)
+            {
+               if(e.type == stringExp && e.string)
+               {
+                  char * string = e.string;
+                  int len = strlen(string);
+                  char * tmp = new char[len-2+1];
+                  len = UnescapeString(tmp, string + 1, len - 2);
+                  delete tmp;
+                  FreeExpContents(exp);
+                  exp.type = constantExp;
+                  exp.constant = PrintUInt(len + 1);
+               }
+               else
+               {
+                  Type type = e.expType;
+                  type.refCount++;
+                  FreeExpContents(exp);
+                  exp.type = constantExp;
+                  exp.constant = PrintUInt(ComputeTypeSize(type));
+                  FreeType(type);
+               }
                break;
             }
             else
@@ -576,16 +603,21 @@ void DebugComputeExpression(Expression exp)
                {
                   if(exp1.type == stringExp)
                   {
-                     int len = exp1.string ? strlen(exp1.string)-2 : 0;
                      uint64 offset = (exp.op.op == '+') ? op2.i64 : -op2.i64;
                      String newString = null;
-                     if(len >= 0 && offset <= len)
+                     if(exp1.string)
                      {
-                        newString = new char[3 + len - offset];
-                        newString[0] = '\"';
-                        memcpy(newString + 1, exp1.string + 1 + offset, len - offset);
-                        newString[1 + len - offset] = '\"';
-                        newString[1 + len - offset + 1] = 0;
+                        int len = strlen(exp1.string) - 2;
+                        char * tmp = OffsetEscapedString(exp1.string + 1, len, (int)offset);
+                        if(tmp)
+                        {
+                           len -= tmp - (exp1.string + 1);
+                           newString = new char[2 + len];
+                           newString[0] = '\"';
+                           memcpy(newString + 1, tmp, len);
+                           newString[1 + len] = '\"';
+                           newString[1 + len + 1] = 0;
+                        }
                      }
                      FreeExpContents(exp);
                      if(newString)
@@ -744,13 +776,20 @@ void DebugComputeExpression(Expression exp)
                      if(exp.index.exp.type == stringExp)
                      {
                         String string = exp.index.exp.string;
-                        int len = string ? strlen(string)-2 : 0;
                         bool valid = false;
                         char ch = 0;
-                        if(len >= 0 && offset <= len)
+                        char * tmp = null;
+                        if(string)
                         {
-                           ch = offset < len ? string[1 + offset] : 0;
-                           valid = true;
+                           int len = string ? strlen(string) : 0;
+                           tmp = new char[len-2+1];
+                           len = UnescapeString(tmp, string + 1, len - 2);
+                           if(len >= 0 && offset <= len)
+                           {
+                              ch = offset < len ? tmp[offset] : 0;
+                              valid = true;
+                           }
+                           delete tmp;
                         }
                         FreeExpContents(exp);
                         if(valid)