Пример #1
0
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();
}
Пример #2
0
bool Gdb_MI2::SetBreakpoint(const String& filename, int line, const String& bp)
{
	String file = Filter(host->GetHostPath(NormalizePath(filename)), CharFilterReSlash2);
	
	// gets all breakpoints
	MIValue bps = GetBreakpoints();
	
	// line should start from 1...
	line++;
	
	// check wether we've got already a breakpoint here
	// and remove it
	MIValue brk = pick(bps.FindBreakpoint(file, line));
	if(!brk.IsEmpty())
		if(!MICmd(Format("break-delete %s", brk["number"].Get())))
		{
			Exclamation(t_("Couldn't remove breakpoint"));
			return false;
		}
	
	if(bp.IsEmpty())
		return true;
	else if(bp[0] == 0xe)
		return MICmd(Format("break-insert %s:%d", file, line));
	else
		return MICmd(Format("break-insert -c \"%s\" %s:%d", bp, file, line));
}
Пример #3
0
static int UppDateSimplify(VarItem &varItem, int step)
{
	MIValue val = varItem.EvaluateExpression(varItem.evaluableExpression);
	val.PackNames();
	int day = atoi(val["day"].ToString());
	int month = atoi(val["month"].ToString());
	int year = atoi(val["year"].ToString());
	varItem.value = Format("Upp::Date = %02d/%02d/%04d", day, month, year);
	return 0;
}
Пример #4
0
static int UppTimeSimplify(VarItem &varItem, int step)
{
	MIValue val = varItem.EvaluateExpression(varItem.evaluableExpression);
	val.PackNames();
	int day = atoi(val[0]["day"].ToString());
	int month = atoi(val[0]["month"].ToString());
	int year = atoi(val[0]["year"].ToString());
	int hour = atoi(val["hour"].ToString());
	int minute = atoi(val["minute"].ToString());
	int second = atoi(val["second"].ToString());
	varItem.value = Format("Upp::Time = %02d/%02d/%04d - %02d:%02d:%02d", day, month, year, hour, minute, second);
	return 0;
}
Пример #5
0
MIValue &MIValue::FindAdd(String const &key, String const &data)
{
	if(IsEmpty())
	{
		Clear();
		type = MITuple;
	}
	if(type != MITuple)
		return  ErrorMIValue("Not a Tuple value type");
	int idx = tuple.Find(key);
	MIValue v;
	v.Set(data);
	if(idx >= 0)
		tuple[idx] = pick(v);
	else
		tuple.AddPick(key, pick(v));
	return *this;
}
Пример #6
0
int MIValue::ParseArray(String const &s, int i)
{
	Clear();
	type = MIArray;
	
	// drop opening delimiter
	if(!expect("ParseArray", '[', i, s))
		return s.GetCount();
	i++;
	while(s[i] && isspace(s[i]))
		i++;
	while(s[i] && s[i] != ']')
	{
		while(s[i] && isspace(s[i]))
			i++;
		String name;
		MIValue val;
		if(s[i] == '[')
			i = val.ParseArray(s, i);
		else if(s[i] == '{')
			i = val.ParseTuple(s, i);
		else if(s[i] == '"')
			i = val.ParseString(s, i);
		else if(s[i] == '<')
			i = val.ParseAngle(s, i);
		else
			i = ParsePair(name, val, s, i);
		array.Add() = pick(val);
		while(s[i] && isspace(s[i]))
			i++;
		if(s[i] == ']')
			break;
		if(!expect("ParseArray", ',', i, s))
			return s.GetCount();
		i++;
	}
	return i + 1;
}
Пример #7
0
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;
}
Пример #8
0
MIValue &MIValue::Add(String const &data)
{
	MIValue v;
	v.Set(data);
	return Add(v);
}
Пример #9
0
int MIValue::ParsePair(String &name, MIValue &val, String const &s, int i)
{
	name.Clear();
	val.Clear();
	while(s[i] && isspace(s[i]))
		i++;
	if(!s[i])
	{
		SetError("ParsePair:Unexpected end of string");
		return i;
	}
	
	// is starting wirh '[' or '{' take it as a value with empty name
	if(s[i] == '{' || s[i] == '[')
	{
		name = "<UNNAMED>";
		return val.ParseTuple(s, i);
	}
	else
	{
		int aCount = 0;
		while(s[i] && ((s[i] != '=' && s[i] != '}' && s[i] != ']' && s[i] != ',') || aCount))
		{
			if(s[i] == '<')
				aCount++;
			else if(s[i] == '>')
				aCount--;
			if(s[i] == '\\')
				name.Cat(backslash(s, i));
			else
				name.Cat(s[i]);
			i++;
			
			// skip blanks if not inside <>
/*
			if(!aCount)
				while(s[i] && isspace(s[i]))
					i++;
*/
		}
		while(s[i] && isspace(s[i]))
			i++;

		if(s[i] != '=')
		{
			// we take the data without = as the value part
			// of keyless tuple...
			val.Set(name);
			name = "<UNNAMED>";
			return i;
		}
		i++;

		while(s[i] && isspace(s[i]))
			i++;
	}

	// skip address part before a tuple start, if any... it's useless and confuses the parser
	if(s[i] == '@')
	{
		int j = i;
		while(s[j] && s[j] != ':')
			j++;
		if(s[j] == ':')
			j++;
		while(s[j] && IsSpace(s[j]))
			j++;
		if(s[j] == '{')
			i = j;
	}

	switch(s[i])
	{
		case '"':
			i = val.ParseString(s, i);
			break;
		break;
		
		case '[':
			i = val.ParseArray(s, i);
			break;
			
		case '{':
			i = val.ParseTuple(s, i);
			break;
			
		default:
			i = val.ParseUnquotedString(s, i);
			break;
	}

	return i;
}
Пример #10
0
static MIValue &ErrorMIValue(String const &msg)
{
	static MIValue v;
	v.SetError(msg);
	return v;
}
Пример #11
0
// read debugger output analyzing command responses and async output
// things are quite tricky because debugger output seems to be
// slow and we have almost no terminator to stop on -- (gdb) is not
// so reliable as it can happen (strangely) in middle of nothing
MIValue Gdb_MI2::ParseGdb(String const &output, bool wait)
{
	MIValue res;
	
	// parse result data
	StringStream ss(output);
	while(!ss.IsEof())
	{
		String s;
		String str = ss.GetLine();
		s = str;
		while(str.GetCount() == 1024 && !ss.IsEof())
		{
			str = ss.GetLine();
			s << str;
		}
		
		s = TrimBoth(s);
		
		// check 'running' and 'stopped' async output
		if(s.StartsWith("*running"))
		{
			started = true;
			stopReason.Clear();
			continue;
		}

		else if(s.StartsWith("*stopped"))
		{
			stopped = true;
			s = '{' + s.Mid(9) + '}';
			stopReason = MIValue(s);
			continue;
		}
		
		// catch process start/stop and store/remove pids
		else if(s.StartsWith("=thread-group-started,id="))
		{
			String id, pid;
			int i = s.Find("id=");
			if(i < 0)
				continue;
			i += 4;
			while(s[i] && s[i] != '"')
				id.Cat(s[i++]);
			i = s.Find("pid=");
			if(i < 0)
				continue;
			i += 5;
			while(s[i] && s[i] != '"')
				pid.Cat(s[i++]);
			
			processes.Add(id, atoi(pid));
			continue;
		}
		
		else if(s.StartsWith("=thread-group-exited,id="))
		{
			String id;
			int i = s.Find("id=");
			if(i < 0)
				continue;
			i += 4;
			while(s[i] && s[i] != '"')
				id.Cat(s[i++]);
			i = processes.Find(id);
			if(i >= 0)
				processes.Remove(i);
			continue;
		}

		// skip asynchronous responses
		// in future, we could be gather/use them
		if(s[0] == '*'|| s[0] == '=')
			continue;
		
		// here handling of command responses
		// we're not interested either, as we use MI interface
		if(s[0] == '~')
			continue;
		
		// here handling of target output
		// well, for now discard this one too, but it should go on console output
		if(s[0] == '~')
			continue;
	
		// here handling of gdb log/debug message
		// not interesting here
		if(s[0] == '&')
			continue;
		
		// now we SHALL have something starting with any of
		// // "^done", "^running", "^connected", "^error" or "^exit" records
		if(s.StartsWith("^done") || s.StartsWith("^running"))
		{
			// here we've got succesful command output in list form, if any
			// shall skip the comma; following can be a serie of pairs,
			// or directly an array of maps in form of :
			// [{key="value",key="value",...},{key="value"...}...]
			
			int i = 5; // just skip shortest, ^done
			while(s[i] && s[i] != ',')
				i++;
			if(!s[i])
				continue;
			i++;
			if(!s[i])
				continue;
			res = MIValue(s.Mid(i));
			continue;
		}
		else if(s.StartsWith("^error"))
		{
			// first array element is reserved for command result status
			s = s.Right(12); // '^error,msg=\"'
			s = s.Left(s.GetCount() - 1);
			res.SetError(s);
		}
		else
			continue;
	}

	return res;
}
Пример #12
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;
}
Пример #13
0
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;
		}
	}

}