Esempio n. 1
0
static MIValue &ErrorMIValue(String const &msg)
{
	static MIValue v;
	v.SetError(msg);
	return v;
}
Esempio n. 2
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;
}