2 jmdict, a frontend to the JMdict file. http://mandrill.fuxx0r.net/jmdict.php
3 Copyright (C) 2004 Florian Bluemel (florian.bluemel@uni-dortmund.de)
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 #include "kana2romaji.h"
33 cout << "jmdict [options] subject\n"
34 " -b search for entries beginning with <subject>\n"
35 " -f perform a fulltext search\n"
36 " -i case-insensitive search (implied by -b or -f)\n"
37 " -r also translate kana to romaji\n"
39 " -j translate from japanese\n"
40 " -J translate to japanese\n"
41 " if neither -j nor -J is given, source language will be guessed\n"
43 " -l lang target language is lang, where lang is a three-letter language code\n"
48 enum Language { UNKNOWN, JAPANESE, JAPANESE_ROMAJI, NOT_JAPANESE };
50 Language source = UNKNOWN;
52 bool fulltext = false;
53 bool beginning = false;
54 bool ci_search = false;
55 bool show_romaji = false;
57 void getFrom(int argc, char** argv) {
59 while ((opt = getopt(argc, argv, "bfirjJl:")) != -1)
61 case 'b': beginning = true; break;
62 case 'f': fulltext = true; break;
63 case 'i': ci_search = true; break;
64 case 'r': show_romaji = true; break;
65 case 'j': source = JAPANESE; break;
66 case 'J': source = NOT_JAPANESE; break;
67 case 'l': target = optarg; break;
68 case '?': throw invalid_argument(string("unrecognized option"));
76 int accumulate(void* to, int, char** what, char**) {
77 string& app = *static_cast<string*>(to);
84 int showGloss(void* s, int, char** value, char**) {
85 string& sense = *static_cast<string*>(s);
86 if (sense != value[0]) {
88 cout << " " << setw(2) << sense << ") ";
92 cout << value[1] << endl;
96 int showEntry(void*, int, char** value, char**) {
99 sql::query("SELECT kanji FROM kanji WHERE entry=%s") % *value,
102 sql::query("SELECT kana FROM reading WHERE entry=%s") % *value,
106 cout << kanji << " (" << kana << ')';
110 if(options::show_romaji) {
112 kana2romaji(kana,rom);
114 cout << " (" << rom << ')';
121 sql::query("SELECT sense, gloss FROM gloss WHERE lang=%Q AND entry=%s "
122 "ORDER BY sense") % options::target % *value,
129 if (options::fulltext)
130 return " LIKE '%%%q%%'";
131 if (options::beginning)
132 return " LIKE '%q%%'";
133 if (options::ci_search)
138 void fromRomaji(const string& r) {
140 sql::query("SELECT DISTINCT entry FROM reading WHERE romaji" + compare()) % r,
144 void fromJapanese(const string& j) {
146 sql::query("SELECT DISTINCT entry FROM reading WHERE kana" + compare()) % j,
149 sql::query("SELECT DISTINCT entry FROM kanji WHERE kanji" + compare()) % j,
153 void toJapanese(const string& e) {
155 q = "SELECT DISTINCT entry FROM gloss WHERE lang=%Q AND gloss" + compare();
156 db->exec(q % options::target % e, showEntry);
159 void guessLanguage(const std::string& subject) {
160 bool isUTF8 = subject[0] & 0x80;
161 if (options::source == options::JAPANESE && !isUTF8)
162 options::source = options::JAPANESE_ROMAJI;
163 else if (options::source == options::UNKNOWN)
164 options::source = isUTF8 ? options::JAPANESE : options::UNKNOWN;
167 int main(int argc, char** argv)
170 options::getFrom(argc, argv);
171 if (optind == argc) {
175 string subject = argv[optind];
176 db.reset(new sql::db(DICTIONARY_PATH));
178 guessLanguage(subject);
179 if (options::source == options::JAPANESE)
180 fromJapanese(subject);
181 else if (options::source == options::JAPANESE_ROMAJI)
183 else if (options::source == options::NOT_JAPANESE)
185 else { /* options::UNKNOWN */
189 cout << entries << " match(es) found." << endl;
193 catch(const std::exception& e)
195 cerr << e.what() << '\n';