#include <stdarg.h>
#include <unistd.h>
#include <ctype.h>
+#include <string.h> // For memchr
#ifdef __APPLE__
#define __unix__
case 0:
snprintf(watchmsg, sizeof(watchmsg), $"Null type for \"%s\"", wh.expression);
break;
- case constantExp:
case stringExp:
+ wh.value = CopyString(exp.string);
+ break;
+ case constantExp:
// Temporary Code for displaying Strings
if((exp.expType && ((exp.expType.kind == pointerType ||
exp.expType.kind == arrayType) && exp.expType.type.kind == charType)) ||
if(exp.expType.kind != arrayType || exp.hasAddress)
{
uint64 address;
- char * string;
char value[4196];
- int len;
//char temp[MAX_F_STRING * 32];
ExpressionType evalError = dummyExp;
strcat(value, $"Null string");
else
{
- int size = 4096;
- len = strlen(value);
- string = null;
- while(!string && size > 2)
+ String string = new char[4097];
+ int start = 0;
+ bool success = false;
+ int size = 256;
+ bool done = false;
+
+ for(start = 0; !done && start + size <= 4096; start += size)
{
- string = GdbReadMemory(address, size);
- size /= 2;
+ String s = null;
+ while(!done && !s)
+ {
+ // Try to read 256 bytes at a time, then half if that fails
+ s = GdbReadMemory(address + start, size);
+ if(s)
+ {
+ success = true;
+ memcpy(string + start, s, size);
+ string[start + size] = 0;
+ if(size == 1 || memchr(s, 0, size))
+ done = true;
+ }
+ else if(size > 1)
+ size /= 2;
+ else
+ done = true;
+ }
+ delete s;
}
- if(string && string[0])
+ if(success)
{
- value[len++] = '(';
- if(UTF8Validate(string))
+ if(string[0])
{
- int c;
- char ch;
+ int len = strlen(value);
+ value[len++] = '(';
+ if(UTF8Validate(string))
+ {
+ int c;
+ char ch;
- for(c = 0; (ch = string[c]) && c<4096; c++)
- value[len++] = ch;
- value[len++] = ')';
- value[len++] = '\0';
+ for(c = 0; (ch = string[c]); c++)
+ value[len++] = ch;
+ value[len++] = ')';
+ value[len++] = '\0';
+ }
+ else
+ {
+ ISO8859_1toUTF8(string, value + len, strlen(value) - len - 30);
+ strcat(value, ") (ISO8859-1)");
+ }
}
else
- {
- ISO8859_1toUTF8(string, value + len, 4096 - len - 30);
- strcat(value, ") (ISO8859-1)");
- }
-
- delete string;
- }
- else if(string)
- {
- strcat(value, $"Empty string");
- delete string;
+ strcat(value, $"Empty string");
}
else
strcat(value, $"Couldn't read memory");
+ delete string;
}
wh.value = CopyString(value);
}
}
if(!ExpressionIsError(exp))
{
+ // Is this necessary here? pass15 had done this already...
+ if(exp.expType) FreeType(exp.expType);
exp.expType = Dereference(exp.index.exp.expType);
- if(exp.index.index && exp.index.index->last && ((Expression)exp.index.index->last) && ((Expression)exp.index.index->last).expType &&
- ((Expression)exp.index.index->last).expType.kind == intType)
+ if(!exp.expType)
{
- uint64 address, offset;
- Expression expNew, last = (Expression)exp.index.index->last;
- //GetUInt(exp.index.exp, &address);
-
- // TOFIX: Check if it has address: TESTING
- if(exp.index.exp.hasAddress && (exp.index.exp.expType.kind == arrayType))
- address = exp.index.exp.address;
- else if(exp.index.exp.type == constantExp)
- GetUInt64(exp.index.exp, &address);
-
- GetUInt64(last, &offset);
- //size = ComputeTypeSize(exp.expType.arrayType); //exp.expType.arrayType.size;
- address += offset * size;
- evaluation = Debugger::ReadMemory(address, size, format, &evalError);
- if(evalError != dummyExp)
- {
- exp.type = evalError;
- exp.constant = CopyString("");
- }
- else if(evaluation)
+ delete evaluation;
+ FreeExpContents(exp);
+ exp.type = dereferenceErrorExp;
+ }
+ else if(exp.index.index && exp.index.index->last && ((Expression)exp.index.index->last) && ((Expression)exp.index.index->last).expType)
+ {
+ Type type = ((Expression)exp.index.index->last).expType;
+ if(type.kind == intType || type.kind == charType || type.kind == shortType || type.kind == int64Type || type.kind == intPtrType ||
+ type.kind == intSizeType || type.kind == longType || type.kind == _BoolType || type.kind == enumType ||
+ (type.kind == classType && type._class && type._class.registered &&
+ type._class.registered.type == enumClass))
{
- expNew = ParseExpressionString(evaluation);
- delete evaluation;
- expNew.destType = exp.expType;
- FreeType(exp.destType);
- FreeExpContents(exp);
- ProcessExpressionType(expNew);
- DebugComputeExpression(expNew);
+ uint64 address = 0, offset = 0;
+ Expression expNew, last = (Expression)exp.index.index->last;
+ //GetUInt(exp.index.exp, &address);
+
+ // TOFIX: Check if it has address: TESTING
+ if(exp.index.exp.hasAddress && (exp.index.exp.expType.kind == arrayType))
+ address = exp.index.exp.address;
+ else if(exp.index.exp.type == constantExp)
+ GetUInt64(exp.index.exp, &address);
+
+ GetUInt64(last, &offset);
+ //size = ComputeTypeSize(exp.expType.arrayType); //exp.expType.arrayType.size;
+ address += offset * size;
+ 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)
+ {
+ ch = offset < len ? string[1 + offset] : 0;
+ valid = true;
+ }
+ FreeExpContents(exp);
+ if(valid)
+ {
+ exp.type = constantExp;
+ exp.constant = PrintChar(ch);
+ }
+ else
+ exp.type = dereferenceErrorExp;
+ }
+ else if(exp.expType.kind == arrayType)
+ {
+ FreeExpContents(exp);
+ exp.type = constantExp;
+ exp.isConstant = true;
+ exp.constant = PrintHexUInt64(address);
+ exp.address = address;
+ exp.hasAddress = true;
+ }
+ else
+ {
+ evaluation = Debugger::ReadMemory(address, size, format, &evalError);
+ switch(evalError)
+ {
+ case dummyExp:
+ if(evaluation)
+ {
+ expNew = ParseExpressionString(evaluation);
+ delete evaluation;
+ expNew.destType = exp.expType;
+ FreeType(exp.destType);
+ FreeExpContents(exp);
+ ProcessExpressionType(expNew);
+ DebugComputeExpression(expNew);
- // TOFIX: Only for Array Types
- expNew.address = address;
+ // TOFIX: Only for Array Types
+ expNew.address = address;
- expNew.hasAddress = true;
- expNew.prev = prev;
- expNew.next = next;
- expNew.isConstant = true;
- *exp = *expNew;
+ expNew.hasAddress = true;
+ expNew.prev = prev;
+ expNew.next = next;
+ expNew.isConstant = true;
+ *exp = *expNew;
+ delete expNew;
+ }
+ else
+ {
+ // Unhandled code path, evaluation is null
+ FreeExpContents(exp);
+ exp.type = unknownErrorExp;
+ }
+ break;
+ case memoryErrorExp:
+ delete evaluation;
+ FreeExpContents(exp);
+ exp.type = evalError;
+ exp.constant = PrintHexUInt64(address);
+ break;
+ default:
+ delete evaluation;
+ FreeExpContents(exp);
+ exp.type = evalError;
+ break;
+ }
+ }
}
- else
- exp.type = unknownErrorExp;
-
- //FreeExpContents(exp);
- //exp.constant = PrintUInt64(value);
- //exp.type = constantExp;
}
}
}