Skip to content

Commit

Permalink
Fix issue #908.
Browse files Browse the repository at this point in the history
Return predefined error codes for certain well known errors.
  • Loading branch information
Andersbakken committed Mar 24, 2017
1 parent 20b3df8 commit 36e8181
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 62 deletions.
36 changes: 22 additions & 14 deletions src/RClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ RClient::RClient()
: mMax(-1), mTimeout(-1), mMinOffset(-1), mMaxOffset(-1),
mConnectTimeout(DEFAULT_CONNECT_TIMEOUT), mBuildIndex(0),
mLogLevel(LogLevel::Error), mTcpPort(0), mGuessFlags(false),
mTerminalWidth(-1)
mTerminalWidth(-1), mExitCode(RTags::ArgumentParseError)
{
struct winsize w;
ioctl(0, TIOCGWINSZ, &w);
Expand Down Expand Up @@ -362,7 +362,7 @@ void RClient::addCompile(Path &&path)
mCommands.append(std::make_shared<CompileCommand>(std::move(path)));
}

int RClient::exec()
void RClient::exec()
{
RTags::initMessages();
OnDestruction onDestruction([]() { Message::cleanup(); });
Expand All @@ -379,7 +379,8 @@ int RClient::exec()
if (!connection->connectTcp(mTcpHost, mTcpPort, mConnectTimeout)) {
if (mLogLevel >= LogLevel::Error)
fprintf(stdout, "Can't seem to connect to server (%s:%d)\n", mTcpHost.constData(), mTcpPort);
return 1;
mExitCode = RTags::ConnectionFailure;
return;
}
connection->connected().connect(std::bind(&EventLoop::quit, loop.get()));
loop->exec(mConnectTimeout);
Expand All @@ -391,32 +392,31 @@ int RClient::exec()
fprintf(stdout, "Can't seem to connect to server (%s)\n", mSocketFile.constData());
}
}
return 1;
mExitCode = RTags::ConnectionFailure;
return;
}
} else if (!connection->connectUnix(mSocketFile, mConnectTimeout)) {
if (mLogLevel >= LogLevel::Error)
fprintf(stdout, "Can't seem to connect to server (%s)\n", mSocketFile.constData());
return 1;
mExitCode = RTags::ConnectionFailure;
return;
}

int ret = 0;
bool hasZeroExit = false;
for (int i=0; i<commandCount; ++i) {
const std::shared_ptr<RCCommand> &cmd = mCommands.at(i);
debug() << "running command " << cmd->description();
if (!cmd->exec(this, connection) || loop->exec(timeout()) != EventLoop::Success) {
ret = 1;
if (!cmd->exec(this, connection)) {
mExitCode = RTags::NetworkFailure;
break;
} else if (loop->exec(timeout()) != EventLoop::Success) {
mExitCode = RTags::TimeoutFailure;
break;
}
if (connection->finishStatus() == 0)
hasZeroExit = true;
mExitCode = connection->finishStatus();
}
if (connection->client())
connection->client()->close();
mCommands.clear();
if (!ret && !hasZeroExit)
ret = connection->finishStatus();
return ret;
}

CommandLineParser::ParseStatus RClient::parse(size_t argc, char **argv)
Expand Down Expand Up @@ -457,9 +457,11 @@ CommandLineParser::ParseStatus RClient::parse(size_t argc, char **argv)
break; }
case Help: {
CommandLineParser::help(stdout, "rc", opts);
mExitCode = RTags::Success;
return { String(), CommandLineParser::Parse_Ok } ; }
case Man: {
CommandLineParser::man(opts);
mExitCode = RTags::Success;
return { String(), CommandLineParser::Parse_Ok }; }
case SocketFile: {
mSocketFile = std::move(value);
Expand Down Expand Up @@ -629,11 +631,13 @@ CommandLineParser::ParseStatus RClient::parse(size_t argc, char **argv)
break; }
case Version: {
fprintf(stdout, "%s\n", RTags::versionString().constData());
mExitCode = RTags::Success;
return { String(), CommandLineParser::Parse_Ok }; }
case VerifyVersion: {
const int version = strtoul(value.constData(), 0, 10);
if (version != NumOptions) {
fprintf(stdout, "Protocol version mismatch\n");
mExitCode = RTags::ProtocolFailure;
return { String(), CommandLineParser::Parse_Error };
}
break; }
Expand Down Expand Up @@ -839,10 +843,12 @@ CommandLineParser::ParseStatus RClient::parse(size_t argc, char **argv)
case FindProjectRoot: {
const Path p = Path::resolved(value); // this won't work correctly with --no-realpath unless --no-realpath is passed first
printf("findProjectRoot [%s] => [%s]\n", p.constData(), RTags::findProjectRoot(p, RTags::SourceRoot).constData());
mExitCode = RTags::Success;
return { String(), CommandLineParser::Parse_Ok }; }
case FindProjectBuildRoot: {
const Path p = Path::resolved(value); // this won't work correctly with --no-realpath unless --no-realpath is passed first
printf("findProjectRoot [%s] => [%s]\n", p.constData(), RTags::findProjectRoot(p, RTags::BuildRoot).constData());
mExitCode = RTags::Success;
return { String(), CommandLineParser::Parse_Ok }; }
case RTagsConfig: {
const Path p = Path::resolved(value); // this won't work correctly with --no-realpath unless --no-realpath is passed first
Expand All @@ -851,6 +857,7 @@ CommandLineParser::ParseStatus RClient::parse(size_t argc, char **argv)
for (const auto &it : config) {
printf("%s: \"%s\"\n", it.first.constData(), it.second.constData());
}
mExitCode = RTags::Success;
return { String(), CommandLineParser::Parse_Ok }; }
case CurrentProject: {
addQuery(QueryMessage::Project, String(), QueryMessage::CurrentProjectOnly);
Expand Down Expand Up @@ -952,6 +959,7 @@ CommandLineParser::ParseStatus RClient::parse(size_t argc, char **argv)
print(CXCursor_FirstAttr, CXCursor_LastAttr);
Log(LogLevel::Error, LogOutput::StdOut | LogOutput::TrailingNewLine) << "Preprocessing:";
print(CXCursor_FirstPreprocessing, CXCursor_LastPreprocessing);
mExitCode = RTags::Success;
return { String(), CommandLineParser::Parse_Ok }; }
case SetBuffers: {
String arg;
Expand Down
4 changes: 3 additions & 1 deletion src/RClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,8 @@ class RClient

RClient();
~RClient();
int exec();
void exec();
int exitCode() const { return mExitCode; }
CommandLineParser::ParseStatus parse(size_t argc, char **argv);

int max() const { return mMax; }
Expand Down Expand Up @@ -217,6 +218,7 @@ class RClient
bool mGuessFlags;
Path mProjectRoot;
int mTerminalWidth;
int mExitCode;
#ifdef RTAGS_HAS_LUA
List<String> mVisitASTScripts;
#endif
Expand Down
12 changes: 12 additions & 0 deletions src/RTags.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,18 @@ String versionString();
const LogLevel DiagnosticsLevel(-2);
const LogLevel Statistics(-3);

enum ExitCodes {
Success = 0,
GeneralFailure = 32,
NetworkFailure = 33,
TimeoutFailure = 34,
NotIndexed = 35,
ConnectionFailure = 36,
ProtocolFailure = 37,
ArgumentParseError = 38,
UnexpectedMessageError = 39,
UnknownMessageError = 40
};
enum UnitType {
CompileC,
CompileCPlusPlus
Expand Down
40 changes: 21 additions & 19 deletions src/Server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -388,11 +388,11 @@ void Server::onNewMessage(const std::shared_ptr<Message> &message, const std::sh
case VisitFileResponseMessage::MessageId:
error() << "Unexpected message" << static_cast<int>(message->messageId());
// assert(0);
connection->finish(1);
connection->finish(RTags::UnexpectedMessageError);
break;
default:
error("Unknown message: %d", message->messageId());
connection->finish(1);
connection->finish(RTags::UnknownMessageError);
break;
}
if ((mOptions.options & (NoFileManagerWatch|NoFileManager)) == NoFileManagerWatch) {
Expand Down Expand Up @@ -776,14 +776,14 @@ void Server::followLocation(const std::shared_ptr<QueryMessage> &query, const st
const Location loc = query->location();
if (loc.isNull()) {
conn->write("Not indexed");
conn->finish(1);
conn->finish(RTags::NotIndexed);
return;
}
std::shared_ptr<Project> project = projectForQuery(query);
if (!project) {
error("No project");
conn->write("Not indexed");
conn->finish(1);
conn->finish(RTags::NotIndexed);
return;
}

Expand All @@ -792,7 +792,7 @@ void Server::followLocation(const std::shared_ptr<QueryMessage> &query, const st
{
FollowLocationJob job(loc, query, project);
if (!job.run(conn)) {
conn->finish(0);
conn->finish();
return;
}
}
Expand All @@ -815,7 +815,7 @@ void Server::followLocation(const std::shared_ptr<QueryMessage> &query, const st
if (path.startsWith(projectPath)) {
FollowLocationJob job(loc, query, proj.second);
if (job.run(conn)) {
conn->finish(0);
conn->finish();
return;
}
}
Expand All @@ -825,8 +825,10 @@ void Server::followLocation(const std::shared_ptr<QueryMessage> &query, const st
}
if (!project->dependencies().contains(loc.fileId())) {
conn->write("Not indexed");
conn->finish(RTags::NotIndexed);
} else {
conn->finish(RTags::GeneralFailure);
}
conn->finish(1);
}

void Server::isIndexing(const std::shared_ptr<QueryMessage> &, const std::shared_ptr<Connection> &conn)
Expand Down Expand Up @@ -898,7 +900,7 @@ void Server::startClangThread(const std::shared_ptr<QueryMessage> &query, const

if (!project->dependencies().contains(fileId)) {
conn->write("Not indexed");
conn->finish(1);
conn->finish(RTags::NotIndexed);
return;
}

Expand Down Expand Up @@ -1068,15 +1070,15 @@ void Server::symbolInfo(const std::shared_ptr<QueryMessage> &query, const std::s
fileId = Location::fileId(path);
if (!fileId) {
conn->write("Not indexed");
conn->finish(1);
conn->finish(RTags::NotIndexed);
return;
}
}

std::shared_ptr<Project> project = projectForQuery(query);
if (!project || !project->dependencies().contains(fileId)) {
conn->write("Not indexed");
conn->finish(1);
conn->finish(RTags::NotIndexed);
return;
}

Expand Down Expand Up @@ -1150,23 +1152,23 @@ void Server::referencesForLocation(const std::shared_ptr<QueryMessage> &query, c
const Location loc = query->location();
if (loc.isNull()) {
conn->write("Not indexed");
conn->finish();
conn->finish(RTags::NotIndexed);
return;
}
std::shared_ptr<Project> project = projectForQuery(query);

if (!project) {
error("No project");
conn->write("Not indexed");
conn->finish();
conn->finish(RTags::NotIndexed);
return;
}

prepareCompletion(query, loc.fileId(), project);

if (!project->dependencies().contains(loc.fileId())) {
conn->write("Not indexed");
conn->finish(1);
conn->finish(RTags::NotIndexed);
return;
}

Expand Down Expand Up @@ -1272,7 +1274,7 @@ void Server::reloadFileManager(const std::shared_ptr<QueryMessage> &query, const
if (project) {
if (mOptions.options & NoFileManager) {
conn->write<512>("Not watching files");
conn->finish(1);
conn->finish(RTags::GeneralFailure);
} else {
conn->write<512>("Reloading files for %s", project->path().constData());
conn->finish();
Expand Down Expand Up @@ -1714,7 +1716,7 @@ void Server::dumpCompileCommands(const std::shared_ptr<QueryMessage> &query, con
project = currentProject();
if (!project) {
conn->write("No current project");
conn->finish(1);
conn->finish(RTags::GeneralFailure);
return;
}

Expand Down Expand Up @@ -1846,20 +1848,20 @@ void Server::classHierarchy(const std::shared_ptr<QueryMessage> &query, const st
const Location loc = query->location();
if (loc.isNull()) {
conn->write("Not indexed");
conn->finish(1);
conn->finish(RTags::NotIndexed);
return;
}
std::shared_ptr<Project> project = projectForQuery(query);
if (!project) {
error("No project");
conn->write("Not indexed");
conn->finish(1);
conn->finish(RTags::NotIndexed);
return;
}

if (!project->dependencies().contains(loc.fileId())) {
conn->write("Not indexed");
conn->finish(1);
conn->finish(RTags::NotIndexed);
return;
}

Expand Down Expand Up @@ -1930,7 +1932,7 @@ void Server::validate(const std::shared_ptr<QueryMessage> &query, const std::sha
if (!project) {
error("No project");
conn->write("No current project");
conn->finish(1);
conn->finish(RTags::GeneralFailure);
return;
}

Expand Down
6 changes: 2 additions & 4 deletions src/rc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,16 @@
int main(int argc, char** argv)
{
RClient rc;
int ret = 0;
const CommandLineParser::ParseStatus status = rc.parse(argc, argv);
switch (status.status) {
case CommandLineParser::Parse_Ok:
break;
case CommandLineParser::Parse_Error:
ret = 1;
fprintf(stderr, "%s\n", status.error.constData());
break;
case CommandLineParser::Parse_Exec:
ret = rc.exec();
rc.exec();
break;
}
return ret;
return rc.exitCode();
}
Loading

0 comments on commit 36e8181

Please sign in to comment.