blob: a54b7d66beaaa8f7dd0329a4dcc4371a4ed0caf9 [file] [log] [blame]
// Copyright 2010-2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "unix/emacs/mozc_emacs_helper_lib.h"
#include <cstdio>
#include <iostream>
#include "base/logging.h"
#include "base/protobuf/descriptor.h"
#include "base/protobuf/message.h"
#include "base/util.h"
#include "base/version.h"
#include "client/client.h"
#include "config/config_handler.h"
#include "session/commands.pb.h"
#include "unix/emacs/client_pool.h"
DEFINE_bool(suppress_stderr, false,
"Discards all the output to stderr.");
namespace {
// Prints a greeting message when a process starts.
void PrintGreetingMessage() {
const mozc::config::Config &config = mozc::config::ConfigHandler::GetConfig();
const char *preedit_method = "unknown";
switch (config.preedit_method()) {
case mozc::config::Config::ROMAN:
preedit_method = "roman";
break;
case mozc::config::Config::KANA:
preedit_method = "kana";
break;
}
fprintf(stdout,
"((mozc-emacs-helper . t)(version . %s)"
"(config . ((preedit-method . %s))))\n",
mozc::emacs::QuoteString(mozc::Version::GetMozcVersion()).c_str(),
preedit_method);
fflush(stdout);
}
// Main loop, which takes an input line as a command and print a corresponding
// result returned by Mozc server in S-expression.
void ProcessLoop() {
using mozc::emacs::ErrorExit;
mozc::emacs::ClientPool client_pool;
mozc::commands::Command command;
string line;
while (getline(cin, line)) {
command.clear_input();
command.clear_output();
uint32 event_id = 0;
uint32 session_id = 0;
// Parse an input line.
mozc::emacs::ParseInputLine(line, &event_id, &session_id,
command.mutable_input());
switch (command.input().type()) {
case mozc::commands::Input::CREATE_SESSION:
session_id = client_pool.CreateClient();
break;
case mozc::commands::Input::DELETE_SESSION:
client_pool.DeleteClient(session_id);
break;
case mozc::commands::Input::SEND_KEY: {
linked_ptr<mozc::client::Client> client =
client_pool.GetClient(session_id);
CHECK(client.get());
if (!client->SendKey(command.input().key(),
command.mutable_output())) {
ErrorExit(mozc::emacs::kErrSessionError, "Session failed");
}
break;
}
default:
ErrorExit(mozc::emacs::kErrVoidFunction, "Unknown function");
}
mozc::emacs::RemoveUsageData(command.mutable_output());
// Output results.
vector<string> buffer;
mozc::emacs::PrintMessage(command.output(), &buffer);
string output;
mozc::Util::JoinStrings(buffer, "", &output);
fprintf(stdout,
"((emacs-event-id . %u)(emacs-session-id . %u)(output . %s))\n",
event_id, session_id, output.c_str());
fflush(stdout);
}
}
} // namespace
int main(int argc, char **argv) {
InitGoogle(argv[0], &argc, &argv, true);
if (FLAGS_suppress_stderr) {
#ifdef OS_WIN
const char path[] = "NUL";
#else
const char path[] = "/dev/null";
#endif
if (!freopen(path, "a", stderr)) {
mozc::emacs::ErrorExit(mozc::emacs::kErrFileError,
"freopen for stderr failed");
}
}
PrintGreetingMessage();
ProcessLoop();
return 0;
}