case '\"':
output[d] = '\"';
break;
+case '\'':
+output[d] = '\'';
+break;
default:
-output[d++] = '\\';
output[d] = ch;
}
d++;
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);
};
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);
__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);
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;
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 { };
// 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);
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
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
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);
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);
// 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
{
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)
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)