You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
156 lines
4.7 KiB
156 lines
4.7 KiB
/***************************************************************************
|
|
* Copyright (C) 2006 Nicolas Hadacek <hadacek@kde.org> *
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
***************************************************************************/
|
|
#include "gpsim.h"
|
|
|
|
#include <tqregexp.h>
|
|
#include "progs/base/generic_prog.h"
|
|
#include "progs/base/generic_debug.h"
|
|
|
|
//-----------------------------------------------------------------------------
|
|
GPSim::Process::Process(Log::Base *base)
|
|
: ::Process::LineOutput(0, "gpsim_process"), Log::Base(base), _ready(false)
|
|
{
|
|
connect(this, TQ_SIGNAL(stdoutDataReceived()), TQ_SLOT(stdoutDataReceivedSlot()));
|
|
}
|
|
|
|
void GPSim::Process::stdoutDataReceivedSlot()
|
|
{
|
|
if ( _stdout.startsWith("**gpsim> ") || _ready ) {
|
|
log(Log::DebugLevel::Extra, "received console prompt", Log::Delayed);
|
|
_ready = true;
|
|
emit requestSynchronousStop();
|
|
}
|
|
}
|
|
|
|
void GPSim::Process::addStdoutLine(const TQString &line)
|
|
{
|
|
log(Log::DebugLevel::Extra, " " + line, Log::Delayed);
|
|
if ( line.startsWith("***ERROR:") ) {
|
|
log(Log::LineType::Error, line);
|
|
return;
|
|
}
|
|
TQString s = line;
|
|
TQString prompt = "**gpsim> ";
|
|
while ( s.startsWith(prompt) ) {
|
|
_ready = true;
|
|
s = s.mid(prompt.length());
|
|
}
|
|
s = s.stripWhiteSpace();
|
|
_stdoutLines += s;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
GPSim::ProcessManager::ProcessManager(Log::Base *base)
|
|
: Log::Base(base), _process(base)
|
|
{}
|
|
|
|
bool GPSim::ProcessManager::start()
|
|
{
|
|
_process._ready = false;
|
|
_process.setup("gpsim", TQStringList("-i"), false);
|
|
if ( !_process.start(0) ) {
|
|
log(Log::LineType::Error, i18n("Failed to start \"gpsim\"."));
|
|
return false;
|
|
}
|
|
return runSynchronously();
|
|
}
|
|
|
|
bool GPSim::ProcessManager::runSynchronously()
|
|
{
|
|
::Process::State state = ::Process::runSynchronously(_process, ::Process::NoRunAction, 5000);
|
|
if ( !_process.isRunning() ) {
|
|
log(Log::LineType::Error, i18n("\"gpsim\" unexpectedly exited."));
|
|
return false;
|
|
}
|
|
if ( state==::Process::Timedout ) {
|
|
log(Log::LineType::Error, i18n("Timeout waiting for \"gpsim\"."));
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool GPSim::ProcessManager::sendCommand(const TQString &cmd, bool synchronous)
|
|
{
|
|
_process._ready = false;
|
|
_process._stdoutLines.clear();
|
|
_process._stdout = TQString();
|
|
_process.writeToStdin(cmd + '\n');
|
|
if (synchronous) return runSynchronously();
|
|
return true;
|
|
}
|
|
|
|
bool GPSim::ProcessManager::sendSignal(uint n, bool synchronous)
|
|
{
|
|
_process._ready = false;
|
|
_process._stdoutLines.clear();
|
|
_process._stdout = TQString();
|
|
if ( !_process.signal(n) ) {
|
|
log(Log::LineType::Error, i18n("Error send a signal to the subprocess."));
|
|
return false;
|
|
}
|
|
if (synchronous) return runSynchronously();
|
|
return true;
|
|
}
|
|
|
|
bool GPSim::ProcessManager::getVersion(VersionData &version)
|
|
{
|
|
if ( !sendCommand("version", true) ) return false;
|
|
TQRegExp reg("\\w*\\s*(\\d+\\.\\d+\\.\\d+).*");
|
|
if ( _process.sout().count()==0 || !reg.exactMatch(_process.sout()[0]) ) {
|
|
version = VersionData();
|
|
return true;
|
|
}
|
|
version = VersionData::fromString(reg.cap(1));
|
|
return true;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
GPSim::Hardware::~Hardware()
|
|
{
|
|
delete _manager;
|
|
}
|
|
|
|
bool GPSim::Hardware::internalConnectHardware()
|
|
{
|
|
delete _manager;
|
|
_manager = new ProcessManager(this);
|
|
_manager->process().setWorkingDirectory(_base.debugger()->directory());
|
|
if ( !_manager->start() ) return false;
|
|
if ( !_manager->getVersion(_version) ) return false;
|
|
if ( !_version.isValid() ) {
|
|
log(Log::LineType::Error, i18n("Could not recognize gpsim version."));
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void GPSim::Hardware::internalDisconnectHardware()
|
|
{
|
|
delete _manager;
|
|
_manager = 0;
|
|
}
|
|
|
|
bool GPSim::Hardware::execute(const TQString &command, bool synchronous, TQStringList *output)
|
|
{
|
|
log(Log::DebugLevel::Normal, TQString("command: %1").arg(command));
|
|
if (output) output->clear();
|
|
if ( !_manager->sendCommand(command, synchronous) ) return false;
|
|
if (output) *output = _manager->process().sout();
|
|
return true;
|
|
}
|
|
|
|
bool GPSim::Hardware::signal(uint n, bool synchronous, TQStringList *output)
|
|
{
|
|
log(Log::DebugLevel::Normal, TQString("signal: %1").arg(n));
|
|
if (output) output->clear();
|
|
if ( !_manager->sendSignal(n, synchronous) ) return false;
|
|
if (output) *output = _manager->process().sout();
|
|
return true;
|
|
}
|