itinial example sentences;added gUI::html_view;doxygen comments
[aoi.git] / src / main.cxx
blobcc7b3319e2e3e81a7b2c3217382037fb760e9932
1 /*
2 Copyright 2013 Karel Matas
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
18 #include "aoi.hxx"
19 #include "utils.hxx"
20 #include "parsers.hxx"
21 #include "sqlite3.hxx"
22 #include "config.hxx"
24 #include <exception>
25 #include <string>
27 using aoi::ElementKanji;
28 using aoi::ElementReading;
29 using aoi::ElementSense;
30 using aoi::DicWord;
31 using aoi::App;
32 using std::string;
33 using utils::to_string;
35 const char *TEMP_JMDICT = "gztemp.jmdict";
36 const char *TEMP_KANJIDIC = "gztemp.kanjidic";
38 /*!
39 * Parses JMDict. File may be GZipped.
40 * \see parsers::JmdictParser
41 * \exception utils::ParsingError
42 * \param fname path to JMDict file
44 void parse_jmdict ( const char *fname )
46 printf("Loading JMdict file '%s'.\n", fname);
47 std::stringstream ss;
48 ss << "BEGIN TRANSACTION;\n";
50 // create parser
51 try {
52 printf("Decompressing file: %s -> %s\n", fname, TEMP_JMDICT);
53 utils::gzip_decompress_file( fname, TEMP_JMDICT);
54 parsers::JmdictParser jmp(TEMP_JMDICT);
55 const char *SEP = aoi::SEPARATOR_SQL;
57 // tables
58 for ( auto &mi: aoi_config::db_tables.at("main") ){
59 if ( strncmp( mi.first, "d_",2 ) !=0 && strcmp( mi.first, "aoi" )!=0 )
60 continue;
61 ss << "DROP TABLE IF EXISTS " << mi.first << ";\n"
62 << "CREATE TABLE " << mi.first << " ( ";
63 for ( size_t i=0; i<mi.second.size(); i++ )
64 ss << mi.second[i].name << " " << mi.second[i].type
65 << ((i==mi.second.size()-1) ? "":",");
66 ss << ");\n";
69 // version
70 ss << "INSERT INTO aoi (key,val) VALUES ('jmdict_version', '"
71 << jmp.get_version() << "');\n";
72 printf("jmdict_version: %s\n", jmp.get_version().c_str());
74 // get entities
75 for ( std::pair<string,string> elt: jmp.get_entities() ){
76 ss << "INSERT INTO d_entities (abbr,desc) VALUES ('" << SQLite3::escape(elt.first)
77 << "','" << SQLite3::escape(elt.second) << "');\n";
80 int n_entries = 1;
81 DicWord entry = jmp.get_entry();
82 while ( entry.did() != -1 ) {
83 for ( ElementReading &rele: entry.r_ele() )
84 ss << rele.sql(entry.did(),SEP);
85 for ( ElementKanji &kele: entry.k_ele() )
86 ss << kele.sql(entry.did(),SEP);
87 for ( ElementSense &sele: entry.s_ele() )
88 ss << sele.sql(entry.did(),SEP);
89 // tbl: header
90 n_entries++;
91 entry = jmp.get_entry();
92 } // while entry
93 printf("%d entries processed.\n", n_entries);
95 catch ( utils::ParsingError &e ){
96 std::string msg = "App::parse_jmdict(): ParsingError: ";
97 msg += e.what();
98 printf("parse_jmdict(): ParsingError: %s\n", e.what() );
99 return;
102 ss << "END TRANSACTION;\n";
103 printf("Writing file 'script.jmdict.sql'...\n");
104 std::ofstream f ("script.jmdict.sql");
105 f << ss.str();
106 f.close();
108 remove(TEMP_JMDICT);
113 * Parses kanjidic2. Works in the same way as parse_jmdict().
114 * \see parsers::KanjidicParser
116 void parse_kanjidic ( const char *fname )
118 printf("Loading kanjidic file: %s\n", fname);
119 const char *SEP = aoi::SEPARATOR_SQL;
121 int n_kanji = 0;
122 try {
123 printf("Decompressing file: %s -> %s\n", fname, TEMP_KANJIDIC);
124 utils::gzip_decompress_file( fname, TEMP_KANJIDIC);
125 parsers::KanjidicParser p(TEMP_KANJIDIC);
126 auto kanji = p.get_entry();
128 std::stringstream ss;
129 ss << "BEGIN TRANSACTION;\n";
131 // tables
132 for ( auto &mi: aoi_config::db_tables.at("main") ){
133 if ( strncmp( mi.first, "k_",2 ) !=0 )
134 continue;
135 ss << "DROP TABLE IF EXISTS " << mi.first << ";\n"
136 << "CREATE TABLE " << mi.first << " ( ";
137 for ( size_t i=0; i<mi.second.size(); i++ )
138 ss << mi.second[i].name << " " << mi.second[i].type
139 << ((i==mi.second.size()-1) ? "":",");
140 ss << ");\n";
143 // version
144 ss << "REPLACE INTO aoi (key,val) VALUES ('kanjidic_version','"
145 << p.get_version() << "');\n";
147 while ( kanji.kanji() != "" ){
148 n_kanji++;
149 ss << "INSERT INTO k_kanji "
150 << "(kanji,ucs,onyomi,kunyomi,meaning,nanori,flags,jlpt,grade,freq,strokes,"
151 << "rad_classic,rad_nelson,components)"
152 << " VALUES('"
153 << kanji.kanji() << "','"
154 << kanji.ucs() << "','"
155 << to_string(kanji.onyomi(),SEP) << "','"
156 << to_string(kanji.kunyomi(),SEP) << "','"
157 << SQLite3::escape(to_string(kanji.meaning(),SEP)) << "','"
158 << to_string(kanji.nanori(),SEP) << "','"
159 << to_string(kanji.flags(),SEP) << "',"
160 << kanji.jlpt() << ","
161 << kanji.grade() << ","
162 << kanji.freq() << ","
163 << kanji.strokes() << ","
164 << kanji.rad_classic() << ","
165 << kanji.rad_nelson() << ","
166 << "''"
167 << ");\n";
168 for ( aoi::SKIP &s: kanji.skip() ) {
169 ss << "INSERT INTO k_skip (kanji,skip1,skip2,skip3,misclass) VALUES('"
170 << kanji.kanji() << "'," << s.s1 << "," << s.s2 << "," << s.s3
171 << ",'" << s.misclass << "');\n";
173 kanji = p.get_entry();
175 ss << "END TRANSACTION\n;";
177 printf("Writing file 'script.kanjidic.sql'...\n");
178 std::ofstream f ("script.kanjidic.sql");
179 f << ss.str();
180 f.close();
182 catch ( utils::ParsingError &e ){
183 printf("parse_kanjidic(): ParsingError: %s\n", e.what());
184 return;
186 remove( TEMP_KANJIDIC );
191 void usage ()
193 printf("USAGE: aoi [OPTIONS]\n");
194 printf("OPTIONS:\n");
195 printf(" -geometry W*H+X+Y \n");
196 printf(" -scheme none|GTK+|plastic \n");
197 printf(" -config config string\n");
198 printf(" -parse jmdict|kanjidic parse either jmdict or kanjidic\n");
202 //////////////////////////////////////////////////////////////////////////
205 int main ( int argc, char **argv )
207 int ret = 0;
208 int fltk_argc = 1;
209 char **fltk_argv = &argv[0];
211 // COmmandline options
212 try {
213 for ( int i=1; i < argc; i++ ){
214 // CONFIG
215 if ( !strcmp( argv[i], "-config") ){
216 string opts = argv[++i];
217 if ( opts == "help" ){
218 for ( auto mi: App::get()->get_config_map() )
219 printf("%s [%s]\n %s\n\n",
220 mi.first.c_str(), mi.second.val.c_str(), mi.second.desc.c_str() );
221 continue;
223 for ( string &s: utils::split_string( opts, ":" ) ){
224 vector<string> kv = utils::split_string(s, "=");
225 App::get()->log("Config override: " + kv[0] + "=" + kv[1]);
226 try {
227 App::get()->config_override( kv[0], kv[1] ); }
228 catch ( std::runtime_error &e ) {
229 App::get()->log_w("Unknown option: " + kv[0] ); }
231 App::get()->apply_config();
232 } // -config
233 // Parse sourcefiles
234 else if ( !strcmp( argv[i], "-parse" ) ) {
235 if ( i == argc-1 ){
236 printf("-parse: Missing parameter: either kanjidic or jmdict\n");
237 return 0;
239 i++;
240 if ( !strcmp( argv[i], "jmdict") ){
241 if ( utils::file_exists("JMdict_e.gz") )
242 parse_jmdict( "JMdict_e.gz" );
243 else if ( utils::file_exists("JMdict_e") )
244 parse_jmdict( "JMdict_e" );
245 else {
246 printf("File not found: JMdict_e or JMdict_e.gz\n");
247 return 0;
250 else if ( !strcmp( argv[i], "kanjidic") ){
251 if ( utils::file_exists("kanjidic2.xml.gz") )
252 parse_kanjidic( "kanjidic2.xml.gz" );
253 else if ( utils::file_exists("kanjidic2.xml") )
254 parse_kanjidic( "kanjidic2.xml" );
255 else {
256 printf("File not found: kanjidic2.xml or kanjidic2.xml.gz\n");
257 return 0;
260 else {
261 printf("-parse: wrong parameter '%s'.\n", argv[i] );
262 printf("Possible parameters: kanjidic or jmdict\n");
264 return 1;
266 else {
267 printf("argv[%d] : %s -> FLTK\n", i, argv[i]);
268 // pass unparsed arguments to FLTK
269 fltk_argv[fltk_argc++] = argv[i];
272 ret = App::get()->run(fltk_argc,fltk_argv);
274 // EXCEPTIONS
275 catch ( std::exception &e ){
276 // This should never happen ...
277 string msg = std::string("Something went wrong...\n")
278 + std::string(typeid(e).name())
279 + std::string(": ") + std::string(e.what());
280 App::get()->alert(msg);
283 delete App::get();
284 return ret;