don't include OpenALBackend.h in qtgui/qtopenc2e.cpp
[openc2e.git] / Catalogue.cpp
blobf55c0996407be45c6ba9901976c4d4a4344d8a14
1 /*
2 * Catalogue.cpp
3 * openc2e
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
23 #include <string>
24 #include <list>
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>
33 #include <iostream>
35 #include <cctype>
37 #include "openc2e.h"
38 #include "util.h"
40 using boost::str;
42 namespace fs = boost::filesystem;
44 Catalogue catalogue;
46 struct quote_subst {
47 char escape;
48 char subst;
51 static struct quote_subst subst_table[] = {
52 { 'n', '\n' },
53 { '\\', '\\' },
54 { '\"', '\"' },
55 { 't', '\t' },
56 { 0, 0 }
59 char catalogue_descape(char c) {
60 struct quote_subst *qs = subst_table;
61 while (qs->escape) {
62 if (qs->escape == c)
63 return qs->subst;
64 qs++;
66 std::cerr << "Unmatched substitution: \\" << c << std::endl;
67 return c;
70 static const char *tok_str[] = { "EOF", "word", "string", "integer" };
72 std::string cat_str;
73 int cat_int = -1;
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)
82 return; // XXX: ?*/
83 data[title].clear();
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;
97 if (err)
98 oss << ": " << err;
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());
106 parsing_cat = &c;
108 cataparse();
110 return s;
113 void Catalogue::reset() {
114 data.clear();
117 void Catalogue::addFile(fs::path path) {
118 assert(fs::exists(path));
119 assert(!fs::is_directory(path));
121 try {
122 fs::ifstream f(path);
123 f >> *this;
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;
136 std::string file;
137 for (fs::directory_iterator i(path); i != end; ++i) {
138 try {
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
147 addFile(*i);
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 {
162 std::string buf;
163 buf = str(boost::format("Agent Help %d %d %d") % (int)family % (int)genus % species);
164 if (hasTag(buf)) {
165 return getTag(buf)[0];
166 } else {
167 return "";
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;
180 return "";
183 /* vim: set noet: */