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"
21 #include "catalogue.lex.h"
22 #include <boost/filesystem/operations.hpp>
23 #include <boost/filesystem/path.hpp>
24 #include <boost/filesystem/fstream.hpp>
25 #include <boost/filesystem/convenience.hpp>
26 #include <boost/tokenizer.hpp>
27 #include <boost/format.hpp>
36 namespace fs
= boost::filesystem
;
45 static struct quote_subst subst_table
[] = {
53 char catalogue_descape(char c
) {
54 struct quote_subst
*qs
= subst_table
;
60 std::cerr
<< "Unmatched substitution: \\" << c
<< std::endl
;
64 static const char *tok_str
[] = { "EOF", "word", "string", "integer" };
69 catalogueFlexLexer
*catalexer
= NULL
;
70 Catalogue
*parsing_cat
= NULL
;
72 void Catalogue::addVals(std::string
&title
, bool override
, int count
,
73 const std::list
<std::string
> &vals
)
75 // 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..
76 /*if (data.find(title) != data.end() && !override)
79 // copy(vals.begin(), vals.end(), data[title].begin());
80 std::list
<std::string
>::const_iterator i
= vals
.begin();
81 while(i
!= vals
.end()) {
82 data
[title
].push_back(*i
++);
87 extern int cataparse();
89 void cataerror(const char *err
) {
90 // XXX: we may leak here - memory pools?
91 throw catalogueException(err
);
93 void catalogueParseError(int lineno
) {
94 std::ostringstream oss
;
95 oss
<< "Catalogue parse error at line " << lineno
<< std::endl
;
97 throw catalogueException(oss
.str());
100 std::istream
&operator >> (std::istream
&s
, Catalogue
&c
) {
101 catalogueFlexLexer
lex(&s
);
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
;