14 #include <boost/algorithm/string/predicate.hpp>
15 #include <boost/algorithm/string/trim.hpp>
16 #include <boost/date_time/gregorian/gregorian.hpp>
17 #include <boost/scoped_ptr.hpp>
18 #include <boost/program_options.hpp>
19 #include <boost/filesystem/convenience.hpp>
20 #include <boost/foreach.hpp>
21 #include <boost/format.hpp>
22 #include <boost/progress.hpp>
23 #include <boost/regex.hpp>
28 #include <tr1/unordered_map>
34 if (tournament.find(name) == 0)
36 else if (tournament.find(name) != tournament.npos)
37 std::cerr << tournament <<
" != " << name <<
"\n";
44 static const osl::CArray<const char*,25> titles = {{
53 std::string name = record.getPlayer(player);
54 std::string title_found =
"";
55 BOOST_FOREACH(
const char *title, titles) {
56 if (boost::algorithm::iends_with(name, title)) {
57 title_found = title + title_found;
58 name.resize(name.size() - strlen(title));
61 record.setPlayer(player, name);
67 boost::scoped_ptr<osl::record::KisenIpxWriter>& ipx_writer,
69 int default_rating,
int min_year,
int max_year)
71 boost::gregorian::date date = record.
getDate();
72 if (min_year > 0 && (date.is_special() || date.year() < min_year))
74 if (max_year > 0 && (date.is_special() || date.year() > max_year))
78 if (check_duplicates.
regist(moves))
86 ipx_writer->save(record, default_rating, default_rating,
87 black_title, white_title);
91 const std::vector<std::string> &
files,
94 int default_rating,
int min_year,
int max_year)
96 std::ofstream ofs(kisen_filename.c_str());
99 boost::scoped_ptr<osl::record::KisenIpxWriter> ipx_writer;
100 boost::scoped_ptr<std::ofstream> ipx_ofs;
103 const boost::filesystem::path ipx_path =
104 boost::filesystem::change_extension(boost::filesystem::path(kisen_filename),
".ipx");
106 ipx_ofs.reset(
new std::ofstream(ipx.c_str()));
110 boost::progress_display progress(files.size());
111 boost::regex date_time_regex(
"/(20[0-9][0-9]/[0-9][0-9]/[0-9][0-9])/");
113 for (
size_t i = 0; i < files.size(); ++i, ++progress)
118 const std::string& filename = files[i];
119 if (boost::algorithm::iends_with(filename,
".kif"))
123 osl::KisenFile kisen(filename);
124 osl::KisenIpxFile ipx(kisen.ipxFileName());
125 for (
size_t j=0; j<kisen.size(); ++j) {
131 record.
setDate(ipx.getStartDate(j));
132 run(record, ks, ipx_writer, check_duplicates,
133 default_rating, min_year, max_year);
135 if (kisen.size() > 0)
143 if (boost::algorithm::iends_with(filename,
".csa"))
148 else if (boost::algorithm::iends_with(filename,
".ki2"))
150 const osl::Ki2File ki2(filename);
151 record = ki2.getRecord();
156 else if (boost::algorithm::iends_with(filename,
".kif"))
158 const osl::KakinokiFile kif(filename);
159 record = kif.getRecord();
163 std::cerr <<
"Unknown file type: " << filename <<
"\n";
166 if (record.
getDate().is_special()) {
168 if (boost::regex_search(filename, match, date_time_regex)) {
169 std::string s(match[1].first, match[1].second);
170 std::cerr <<
"use date in path " << s <<
"\n";
171 record.
setDate(boost::gregorian::from_string(s));
174 run(record, ks, ipx_writer, check_duplicates, default_rating, min_year, max_year);
176 catch(std::exception& e)
178 std::cerr <<
"ERROR: reading " << files[i] <<
"; " <<
179 e.what() << std::endl;
185 int main(
int argc,
char **argv)
189 int default_rating, year, min_year, max_year;
190 boost::program_options::options_description command_line_options;
191 command_line_options.add_options()
193 boost::program_options::value<bool>(&output_ipx)->default_value(
true),
194 "Whether output IPX file in addition to KIF file")
195 (
"tournament-file", boost::program_options::value<std::string>(&tournament_filename)
197 "ignore records unless the name of their tournament is listed in the file in EUC-JP")
198 (
"year", boost::program_options::value<int>(&year)->default_value(0),
199 "year to select (0 for all)")
200 (
"min-year", boost::program_options::value<int>(&min_year)->default_value(0),
201 "min year to select (0 for all)")
202 (
"max-year", boost::program_options::value<int>(&max_year)->default_value(0),
203 "max year to select (0 for all)")
205 boost::program_options::value<std::string>(&kisen_filename)->
206 default_value(
"test.kif"),
207 "Output filename of Kisen file")
208 (
"input-file", boost::program_options::value< std::vector<std::string> >(),
209 "input files in kisen format")
210 (
"default-rating", boost::program_options::value<int>(&default_rating)->
213 (
"help",
"Show help message");
214 boost::program_options::variables_map
vm;
215 boost::program_options::positional_options_description p;
216 p.add(
"input-file", -1);
221 boost::program_options::command_line_parser(
222 argc, argv).options(command_line_options).positional(p).
run(), vm);
223 boost::program_options::notify(vm);
224 if (vm.count(
"help"))
226 std::cerr <<
"Usage: " << argv[0] <<
" [options] csa-files | ki2-files \n";
227 std::cerr <<
" " << argv[0] <<
" [options]\n";
228 std::cout << command_line_options << std::endl;
232 catch (std::exception &e)
234 std::cerr <<
"error in parsing options" << std::endl
235 << e.what() << std::endl;
236 std::cerr <<
"Usage: " << argv[0] <<
" [options] csa-files | ki2-files\n";
237 std::cerr <<
" " << argv[0] <<
" [options]\n";
238 std::cerr << command_line_options << std::endl;
242 if (tournament_filename !=
"")
244 std::ifstream is(tournament_filename.c_str());
246 while(std::getline(is, name))
248 boost::algorithm::trim(name);
252 throw std::runtime_error(
"read failed "+tournament_filename);
255 min_year = max_year = year;
257 std::vector<std::string>
files;
258 if (vm.count(
"input-file"))
260 const std::vector<std::string> temp = vm[
"input-file"].as<std::vector<std::string> >();
261 files.insert(files.end(), temp.begin(), temp.end());
266 while(std::getline(std::cin , line))
268 boost::algorithm::trim(line);
269 files.push_back(line);
274 convert(kisen_filename, files, output_ipx, check_duplicate, default_rating,
277 std::locale::global(std::locale(
""));
278 check_duplicate.
print(std::cout);