5 * Created by Alyssa Milburn on Sat 13 Nov 2004.
6 * Copyright (c) 2004-2006 Alyssa Milburn. All rights reserved.
7 * Copyright (c) 2005-2006 Bryan Donlan. All rights reserved.
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
20 #include "Catalogue.h"
22 // make sure we have the header imports that bison's horrible .h file needs
26 #include "catalogue.tab.hpp"
27 #include <boost/filesystem/operations.hpp>
28 #include <boost/filesystem/path.hpp>
29 #include <boost/filesystem/fstream.hpp>
30 #include <boost/filesystem/convenience.hpp>
31 #include <boost/tokenizer.hpp>
32 #include <boost/format.hpp>
42 namespace fs
= boost::filesystem
;
51 static struct quote_subst subst_table
[] = {
59 char catalogue_descape(char c
) {
60 struct quote_subst
*qs
= subst_table
;
66 std::cerr
<< "Unmatched substitution: \\" << c
<< std::endl
;
70 static const char *tok_str
[] = { "EOF", "word", "string", "integer" };
75 Catalogue
*parsing_cat
= NULL
;
77 void Catalogue::addVals(std::string
&title
, bool override
, int count
,
78 const std::list
<std::string
> &vals
)
80 // TODO: how the heck does override work? DS has an "Option Text" tag which has to overwrite the C3 one, so commenting this out for now..
81 /*if (data.find(title) != data.end() && !override)
84 // copy(vals.begin(), vals.end(), data[title].begin());
85 std::list
<std::string
>::const_iterator i
= vals
.begin();
86 while(i
!= vals
.end()) {
87 data
[title
].push_back(*i
++);
92 extern int cataparse();
94 void Catalogue::catalogueParseError(const char *err
) {
95 std::ostringstream oss
;
96 oss
<< "Catalogue parse error at line " << yylineno
;
100 throw catalogueException(oss
.str());
103 std::istream
&operator >> (std::istream
&s
, Catalogue
&c
) {
104 std::string buf
= readfile(s
);
105 Catalogue::yyinit(buf
.c_str());
113 void Catalogue::reset() {
117 void Catalogue::addFile(fs::path path
) {
118 assert(fs::exists(path
));
119 assert(!fs::is_directory(path
));
122 fs::ifstream
f(path
);
124 } catch (const catalogueException
&ex
) {
125 std::cerr
<< "Error reading catalogue file " << path
.string() << ":" << std::endl
<< '\t' << ex
.what() << std::endl
;
129 void Catalogue::initFrom(fs::path path
) {
130 assert(fs::exists(path
));
131 assert(fs::is_directory(path
));
133 //std::cout << "Catalogue is reading " << path.native_directory_string() << std::endl;
135 fs::directory_iterator end
;
137 for (fs::directory_iterator
i(path
); i
!= end
; ++i
) {
139 if ((!fs::is_directory(*i
)) && (fs::extension(*i
) == ".catalogue")) {
140 std::string x
= fs::basename(*i
);
141 // TODO: '-en-GB' exists too, this doesn't work for that
142 if ((x
.size() > 3) && (x
[x
.size() - 3] == '-')) {
143 // TODO: this is NOT how we should do it
144 if (x
[x
.size() - 2] != 'e' || x
[x
.size() - 1] != 'n') continue; // skip all non-english localised files
150 catch (const std::exception
&ex
) {
151 std::cerr
<< "directory_iterator died on '" << i
->leaf() << "' with " << ex
.what() << std::endl
;
156 std::string
stringFromInt(int i
) {
157 // TODO: hacky? also, put somewhere more appropriate
158 return boost::str(boost::format("%d") % i
);
161 const std::string
Catalogue::getAgentName(unsigned char family
, unsigned char genus
, unsigned short species
) const {
163 buf
= str(boost::format("Agent Help %d %d %d") % (int)family
% (int)genus
% species
);
165 return getTag(buf
)[0];
171 std::string
Catalogue::calculateWildcardTag(std::string tag
, unsigned char family
, unsigned char genus
, unsigned short species
) const {
172 std::string searchstring
= tag
+ " " + stringFromInt(family
) + " " + stringFromInt(genus
) + " " + stringFromInt(species
);
173 if (hasTag(searchstring
)) return searchstring
;
174 searchstring
= tag
+ " " + stringFromInt(family
) + " " + stringFromInt(genus
) + " 0";
175 if (hasTag(searchstring
)) return searchstring
;
176 searchstring
= tag
+ " " + stringFromInt(family
) + " 0 0";
177 if (hasTag(searchstring
)) return searchstring
;
178 searchstring
= tag
+ " 0 0 0";
179 if (hasTag(searchstring
)) return searchstring
;