static int UppOneSimplify(VarItem &varItem, int step) { // setup item type varItem.kind = VarItem::COMPLEX; // if we're just doing first scan phase, signal that we need further evaluation later #ifdef EVALDEEP if(!step) // next step is 1 return 1; #else varItem.value = placeHolder; return 0; #endif // de-reference and forward simplify MIValue val = varItem.EvaluateExpression(varItem.evaluableExpression + "." + "ptr"); if(val.IsError() || !val.IsString()) { varItem.value = "Upp::One<> = <can't evaluate contents>"; return 0; } String ptr = val.ToString(); if(ptr == "0x0") { varItem.value = "Upp::One<> = <EMPTY>"; return 0; } // replace variable with de-referenced one VarItem vItem(&varItem.Debugger(), "*" + varItem.evaluableExpression + "." + "ptr"); varItem = vItem; return varItem.GetSimplifyStep(); }
static int UppStringSimplify(VarItem &varItem, int step) { enum { SMALL = 0, MEDIUM = 31 }; // SMALL has to be 0 because of GetSpecial and because is it ending zero enum { KIND = 14, SLEN = 15, LLEN = 2, SPECIAL = 13 }; union { char chr[16]; char *ptr; dword *wptr; qword *qptr; word v[8]; dword w[4]; qword q[2]; } u; // see Upp::String code for how it works.... MIValue val = varItem.EvaluateExpression("(" + varItem.evaluableExpression + ")." + "chr"); if(!val.IsString()) return 0; String chrs = val.ToString(); memcpy(u.chr, ~chrs, 16); bool isSmall = (u.chr[14] == 0); String s; if(isSmall) { byte len = u.chr[SLEN]; s = chrs.Left(len); } else { dword len = u.w[LLEN]; MIValue val = varItem.EvaluateExpression("(" + varItem.evaluableExpression + ").ptr[0]@" + FormatInt(len)); if(!val.IsString()) return 0; s = val.ToString(); } varItem.value = "\"" + s + "\""; varItem.kind = VarItem::SIMPLE; return 0; }
static int UppVectorSimplify(VarItem &varItem, int step) { // setup item type varItem.kind = VarItem::ARRAY; // if we're just doing first scan phase, signal that we need further evaluation later #ifdef EVALDEEP if(!step) // next step is 1 return 1; #else varItem.value = placeHolder; return 0; #endif // just getting items count... if(step == 1) { // initialize default value varItem.value = "<can't evaluate>"; // get items count MIValue val = varItem.EvaluateExpression(varItem.evaluableExpression + ".items"); if(val.IsError() || !val.IsString()) return 0; varItem.items = atoi(val.ToString()); // update value varItem.value = Format("Upp::Vector with %d elements", varItem.items, ""); // if no elements, just quit if(!varItem.items) return 0; return 2; } int count = min(EVALDEEP_VECTOR, varItem.items); // start from item 0 step -= 2; // fetch elements, check on first if they're SIMPLE, so displayable VarItem vItem(&varItem.Debugger(), varItem.evaluableExpression + Format(".vector[%d]", step)); if(!vItem) { varItem.value << " <can't evaluate contents>"; return 0; } if(vItem.kind != VarItem::SIMPLE) { varItem.value << " = [...]"; return 0; } vItem.Simplify(); if(!step) varItem.value << " = [ ]"; const char *sep = step ? " , " : ""; varItem.value = varItem.value.Left(varItem.value.GetCount() - 2) + sep + vItem.value + " ]"; if(++step >= count) return 0; else return step + 2; }
static int UppValueSimplify(VarItem &varItem, int step) { enum { SMALL = 0, MEDIUM = 31 }; // SMALL has to be 0 because of GetSpecial and because is it ending zero enum { KIND = 14, SLEN = 15, LLEN = 2, SPECIAL = 13 }; enum { STRING = 0, REF = 255, VOIDV = 3 }; // get the embedded 'data' string 'chr' member // it contains info about value type union { char chr[16]; char *ptr; dword *wptr; qword *qptr; word v[8]; dword w[4]; qword q[2]; int iData; int64 i64Data; double dData; bool bData; struct { byte day; byte month; int16 year; byte hour; byte minute; byte second; }; } u; // see Upp::String code for how it works.... MIValue val = varItem.EvaluateExpression("(" + varItem.evaluableExpression + ").data.chr"); if(!val.IsString()) return 0; String chrs = val.ToString(); memcpy(u.chr, ~chrs, 16); // get value type, among the fixed ones // we could try later to decode registered types.... dword type; bool isSpecial = !u.v[7] && u.v[6]; if(!isSpecial) type = STRING_V; else { byte st = u.chr[SPECIAL]; if(st == REF) { // ptr()->GetType() // by now, just mark as ref... type = REF; } else if(st == VOIDV) type = VOID_V; else type = st; } // by now, treat all types beyond VALUEMAP_V as unknown if(type > VALUEMAP_V) type = UNKNOWN_V; // now, based on type, we can decode it varItem.kind = VarItem::SIMPLE; switch(type) { case VOID_V: { varItem.value = "<VOID>"; return 0; } case INT_V: { varItem.value = FormatInt(u.iData); return 0; } case DOUBLE_V: { varItem.value = FormatDouble(u.dData); return 0; } case STRING_V: { // we simply replace the VarItem with the string VarItem vItem(&varItem.Debugger(), "(" + varItem.evaluableExpression + ").data"); vItem.evaluableExpression = varItem.evaluableExpression; vItem.shortExpression = varItem.shortExpression; varItem = vItem; return 0; } case DATE_V: { varItem.value = Format("Upp::Date = %02d/%02d/%04d", u.day, u.month, u.year); return 0; } case TIME_V: { varItem.value = Format("Upp::Time = %02d/%02d/%04d - %02d:%02d:%02d", u.day, u.month, u.year, u.hour, u.minute, u.second); return 0; } break; case ERROR_V: { varItem.value = "<ERROR_V>"; return 0; } case VALUE_V: { varItem.value = "<VALUE_V>"; return 0; } case WSTRING_V: { varItem.value = "<WSTRING_V>"; return 0; } case VALUEARRAY_V: { varItem.value = "<VALUEARRAY_V>"; return 0; } case INT64_V: { varItem.value = FormatInt64(u.i64Data); return 0; } case BOOL_V: { varItem.value = (u.bData ? "TRUE" : "FALSE"); return 0; } case VALUEMAP_V: { varItem.value = "<VALUEMAP_V>"; return 0; } case UNKNOWN_V: default: { varItem.value = "<UNKNOWN_V>"; return 0; } } }