/***************************************************************************
* Copyright (C) 2005 by TAM(Teppei Tamra) *
* tam-t@par.odn.ne.jp *
* *
* 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. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include "primeprediction.h"
#include <honoka_plugin_def.h>
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifdef HAVE_GETTEXT
#include <libintl.h>
#define _(String) dgettext(GETTEXT_PACKAGE,String)
#define N_(String) (String)
#else
#define _(String) (String)
#define N_(String) (String)
#define bindtextdomain(Package,Directory)
#define textdomain(domain)
#define bind_textdomain_codeset(domain,codeset)
#endif
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/shm.h>
// プライグイン化のおまじないです。
HonokaPluginRegister(PrimePrediction);
HonokaPluginSetup(
vector<String> l;
HonokaSetupPage *page = new HonokaSetupPage(_("PrimePrediction-plugin"),"","");
page->append(new HonokaSetupBoolItem(
_("_Use this plugin: "),
String(HONOKA_CONFIG_PLUGINLOADER_PREFIX) + String("/plugin-prime"),
_("if you use this plugin, check this."),
true
));
l.clear();
l.push_back(String("lookup"));
l.push_back(String("lookup_all"));
l.push_back(String("lookup_compact"));
l.push_back(String("lookup_compact_all"));
l.push_back(String("lookup_direct"));
l.push_back(String("lookup_direct_all"));
l.push_back(String("lookup_exact"));
l.push_back(String("lookup_expansion"));
l.push_back(String("lookup_hybrid"));
l.push_back(String("lookup_hybrid_all"));
l.push_back(String("lookup_mixed"));
page->append(new HonokaSetupSelectItem(
_("_Lookup method: "),
HONOKA_CONFIG_PRIME_PREDICTION_LM,
_("select the lookup method."),
HONOKA_DEFAULT_PRIME_PREDICTION_LM,
l
));
return page;
);
PrimePrediction::PrimePrediction(ConfigPointer cfg) : Predictor(cfg)
{
m_iconv.set_encoding ("EUC-JP");
mid = shmget(IPC_PRIVATE,sizeof(bool),IPC_CREAT | 0666);
if (mid != -1) {
con = (bool *)shmat(mid,0,0);
con[0] = false;
// shmat失敗時のエラー処理は?。
// 同一プロセスで確実に同じIDなら失敗しようがない気もするが。
}
lookup_method = cfg->read(HONOKA_CONFIG_PRIME_PREDICTION_LM,String(HONOKA_DEFAULT_PRIME_PREDICTION_LM));
if ((lookup_method != "lookup") &&
(lookup_method != "lookup_all") &&
(lookup_method != "lookup_compact") &&
(lookup_method != "lookup_compact_all") &&
(lookup_method != "lookup_direct") &&
(lookup_method != "lookup_direct_all") &&
(lookup_method != "lookup_exact") &&
(lookup_method != "lookup_expansion") &&
(lookup_method != "lookup_hybrid") &&
(lookup_method != "lookup_hybrid_all") &&
(lookup_method != "lookup_mixed")) lookup_method = String(HONOKA_DEFAULT_PRIME_PREDICTION_LM);
}
PrimePrediction::~PrimePrediction()
{
disconnect();
if (mid != -1) shmctl(mid,IPC_RMID,0);
}
/*!
\fn PrimePrediction::parser(const String &str)
*/
ResultEntry PrimePrediction::parser(const String &str)
{
vector<String> rl;
String r;
for(unsigned int i = 0;i < str.length();i ++) {
if ((str[i] == '\t') || (str[i] == ' ')) {
if (r.length()) {
rl.push_back(r);
r = "";
}
} else r += str[i];
}
if (r.length()) rl.push_back(r);
if (rl.size() < 2) return ResultEntry();
WideString w,a;
for(unsigned int i = 2;i < rl.size();i ++) {
if (rl[i].length() < 7) continue;
if (rl[i].substr(0,6) == "usage=") m_iconv.convert(a,rl[i].substr(6));
}
m_iconv.convert(w,rl[1]);
if (!a.length()) a = w;
else a = w + utf8_mbstowcs(String(" (")) + a + utf8_mbstowcs(String(")"));
return ResultEntry(w,a);
}
/*!
\fn PrimePrediction::getPredictionList(const WideString &str)
*/
ResultList PrimePrediction::getPredictionList(const WideString &str)
{
ResultList l;
if (mid == -1) return l;
if (!con[0]) return l;
String s = lookup_method + "\t";
String t;
m_iconv.convert(t,str);
s = s + t + String("\n");
write(ifd,s.c_str(),s.length());
char b[1024];
vector<String> sl;
s = "";
while(-1) {
int c = read(ofd,b,1023);
s += String(b,c);
if (s.substr(s.length() - 2,2) == "\n\n") break;
}
t = "";
for(unsigned int i = 0;i < s.length();i ++) {
if (s[i] == '\n') {
sl.push_back(t);
t = "";
} else t += s[i];
}
if (t.length()) sl.push_back(t);
l.Title = utf8_mbstowcs(String(_("lookup result")));
l.kType = PREDICTION;
for(unsigned int i = 1;i < sl.size();i ++) {
ResultEntry e = parser(sl[i]);
if (e.kanji.length()) l.kouho.push_back(e);
}
return l;
}
/*!
\fn PrimePrediction::disconnect()
*/
void PrimePrediction::disconnect()
{
if (mid == -1) return;
if (con[0]) return;
String s = "close\n";
write(ifd,s.c_str(),s.length());
close(ifd);
close(ofd);
con[0] = false;
}
/*!
\fn PrimePrediction::connect()
*/
bool PrimePrediction::connect()
{
if (mid == -1) return false;
int in_fd[2],out_fd[2],i;
if (con[0]) return true;
if (pipe(in_fd) == -1) return false;
if (pipe(out_fd) == -1) return false;
switch(fork()) {
case -1: {
close(in_fd[0]);
close(in_fd[1]);
close(out_fd[0]);
close(out_fd[1]);
con[0] = false;
return false;
}
case 0: {
close(in_fd[1]);
close(out_fd[0]);
dup2(in_fd[0],0);
dup2(out_fd[1],1);
close(in_fd[0]);
close(out_fd[1]);
con[0] = true;
execlp("prime",NULL);
con[0] = false;
_exit(0);
}
}
close(in_fd[0]);
close(out_fd[1]);
ifd = in_fd[1];
ofd = out_fd[0];
return true;
}
/*!
\fn PrimePrediction::isConnected()
*/
bool PrimePrediction::isConnected()
{
if (mid == -1) return false;
return con[0];
}
/*!
\fn PrimePrediction::getPropertyName()
*/
String PrimePrediction::getPropertyName()
{
return String(_("PrimePrediction"));
}
/*!
\fn PrimePrediction::getName()
*/
String PrimePrediction::getName()
{
return String("PrimePrediction");
}
/*!
\fn PrimePrediction::update(const WideString str,const WideString yomi)
*/
void PrimePrediction::update(const WideString str,const WideString yomi)
{
}