added and tested LocalModList class, corrected some bugs

master
Phitherek 2013-03-27 13:41:33 +01:00
parent 707307343b
commit 501b2f5b5b
12 changed files with 450 additions and 3 deletions

38
3m.h Normal file
View File

@ -0,0 +1,38 @@
#ifndef _3M_H
#define _3M_H
#include <string>
#include "ConfigFile.h"
#include "3mExceptions.h"
#include "LocalModDescription.h"
#include "ModDescription.h"
#include "ModInfoDescription.h"
#include "ModListDescription.h"
#include "ModListList.h"
#include "RepositoryModDescription.h"
#include "LocalModList.h"
/// \file 3m.h
/// \brief A common header for 3m and definitions of helper functions.
/// \author Phitherek_
/// \date 2013
/// \version 0.1
/// \namespace mmm
/// \brief A global namespace for 3m.
namespace mmm {
/// \fn std::string strip_endl(std::string s)
/// \brief A function that strips endline signs from the string.
/// \param s A string to strip endline signs from.
/// \return Stripped string.
std::string strip_endl(std::string s) {
int len = s.length();
for(int i = 0; i < len; i++) {
if(s[i] == '\n') {
s.erase(i,1);
len = s.length();
i--;
}
}
return s;
}
}
#endif

View File

@ -16,3 +16,15 @@ std::string LocalModDescription::getRemoteModlistName() {
void LocalModDescription::setRemoteModlistName(std::string remoteModlist) {
_remoteModlist = remoteModlist;
}
void LocalModDescription::clear() {
_name = "";
_description = "";
_release = 0;
_depsIterator = -1;
_depsAtEnd = true;
_repotype = "";
_repoaddr = "";
_deps.clear();
_remoteModlist = "";
}

View File

@ -22,6 +22,7 @@ std::string getRemoteModlistName(); ///< \brief A function returning remote modl
///< \return Remote modlist name.
void setRemoteModlistName(std::string remoteModlist); ///< \brief A function setting remote modlist name.
///< \param remoteModlist Remote modlist name
void clear(); ///< A function that clears the object.
};
}
#endif

260
LocalModList.cpp Normal file
View File

@ -0,0 +1,260 @@
#include "3m.h"
#include <fstream>
#include <cstdlib>
using namespace mmm;
LocalModList::LocalModList() {
ConfigFile emptycf;
_conf = emptycf;
_modlistIterator = -1;
_modlistAtEnd = true;
_modlist.clear();
}
LocalModList::LocalModList(ConfigFile conf) {
_conf = conf;
_modlist.clear();
std::ifstream lmfile(_conf.getModList().c_str());
if(!lmfile) {
throw FileException(_conf.getModList(), "reading", "Could not open file!");
}
std::string action = "detect";
LocalModDescription lmld;
while(!lmfile.eof()) {
std::string line = "";
char c;
do {
lmfile.get(c);
if(c != '\n');
line += c;
} while(c != '\n');
line = strip_endl(line);
if(lmfile) {
if(action == "detect") {
if(line[0] == '{') {
std::string name = "";
for(unsigned int i = 1; line[i] != '}' && i < line.length(); i++) {
name += line[i];
}
lmld.setName(name);
action = "parse";
} else {
std::string msg = "";
msg = "Found ";
msg += line[0];
msg += " although { was expected.";
lmfile.close();
throw ParseException(_conf.getModList(), msg);
}
} else if(action == "parse") {
if(line[0] == '{') {
if(line[1] == 'e' && line[2] == 'n' && line[3] == 'd' && line[4] == '}') {
if(lmld.getName() != "" && lmld.getRemoteModlistName() != "" && lmld.getDescription() != "" && !lmld.dependenciesEmpty() && lmld.getRepositoryType() != "" && lmld.getRepositoryAddress() != "") {
_modlist.push_back(lmld);
if(_modlistAtEnd) {
_modlistAtEnd = false;
}
lmld.clear();
action = "detect";
} else {
lmfile.close();
throw ParseException(_conf.getModList(),"Data error.");
}
action = "detect";
} else {
lmfile.close();
std::string msg;
msg = "Found ";
msg += line;
msg += " although {end} or action in [] was expected.";
throw ParseException(_conf.getModList(), msg);
}
} else if(line[0] == '[') {
std::string tmpact = "";
for(unsigned int i = 1; line[i] != ']' && i < line.length(); i++) {
tmpact += line[i];
}
if(tmpact == "rmodlist" || tmpact == "description" || tmpact == "release" || tmpact == "deps" || tmpact == "repotype" || tmpact == "repoaddr") {
action = tmpact;
} else {
std::string msg;
msg = "Found ";
msg += tmpact;
msg += " although rmodlist/description/release/deps/repotype/repoaddr was expected.";
lmfile.close();
throw ParseException(_conf.getModList(), msg);
}
} else {
std::string msg;
msg = "Found ";
msg += line;
msg += " although {end} or action in [] was expected.";
lmfile.close();
throw ParseException(_conf.getModList(), msg);
}
} else if(action == "rmodlist") {
if(line[0] == '[' || line[0] == '{') {
std::string msg;
msg = "Found ";
msg += line[0];
msg += " although string was expected.";
lmfile.close();
throw(_conf.getModList(), msg);
} else {
lmld.setRemoteModlistName(line);
action = "parse";
}
} else if(action == "description") {
if(line[0] == '[' || line[0] == '{') {
std::string msg;
msg = "Found ";
msg += line[0];
msg += " although string was expected.";
lmfile.close();
throw(_conf.getModList(), msg);
} else {
lmld.setDescription(line);
action = "parse";
}
} else if(action == "release") {
if(line[0] == '[' || line[0] == '{') {
std::string msg;
msg = "Found ";
msg += line[0];
msg += " although string was expected.";
lmfile.close();
throw(_conf.getModList(), msg);
} else {
lmld.setReleaseNr(atoi(line.c_str()));
action = "parse";
}
} else if(action == "deps") {
if(line[0] == '{') {
std::string msg;
msg = "Found ";
msg += line[0];
msg += " although string or [ was expected.";
lmfile.close();
throw(_conf.getModList(), msg);
} else if(line[0] == '[') {
if(line[1] == 'd' && line[2] == 'e' && line[3] == 'p' && line[4] == 's' && line[5] == 'e' && line[6] == 'n' && line[7] == 'd' && line[8] == ']') {
if(lmld.dependenciesEmpty()) {
lmld.insertDependency("none");
}
action = "parse";
} else {
std::string msg;
msg = "Found ";
msg += line;
msg += " although string or [depsend] was expected.";
lmfile.close();
throw(_conf.getModList(), msg);
}
} else {
lmld.insertDependency(line);
}
} else if(action == "repotype") {
if(line[0] == '[' || line[0] == '{') {
std::string msg;
msg = "Found ";
msg += line[0];
msg += " although string was expected.";
lmfile.close();
throw(_conf.getModList(), msg);
} else {
lmld.setRepositoryType(line);
action = "parse";
}
} else if(action == "repoaddr") {
if(line[0] == '[' || line[0] == '{') {
std::string msg;
msg = "Found ";
msg += line[0];
msg += " although string was expected.";
lmfile.close();
throw(_conf.getModList(), msg);
} else {
lmld.setRepositoryAddress(line);
action = "parse";
}
} else {
lmfile.close();
throw ParseException(_conf.getModList(), "The program should not reach this place!");
}
}
}
lmfile.close();
_modlistIterator = -1;
_modlistAtEnd = true;
}
LocalModList::~LocalModList() {
ConfigFile emptycf;
_conf = emptycf;
_modlist.clear();
_modlistIterator = -1;
_modlistAtEnd = true;
}
void LocalModList::addModDescription(LocalModDescription lmd) {
_modlist.push_back(lmd);
if(_modlistAtEnd) {
_modlistAtEnd = false;
}
}
LocalModDescription LocalModList::getNextModDescription() {
if(_modlistIterator+1 < _modlist.size()) {
_modlistIterator++;
return _modlist[_modlistIterator];
} else {
_modlistAtEnd = true;
LocalModDescription emptylmd;
return emptylmd;
}
}
LocalModDescription LocalModList::getModDescriptionByName(std::string name) {
for(unsigned int i = 0; i < _modlist.size(); i++) {
if(_modlist[i].getName() == name) {
return _modlist[i];
}
}
LocalModDescription emptylmd;
return emptylmd;
}
void LocalModList::resetModDescriptionIterator() {
if(_modlistAtEnd) {
_modlistAtEnd = false;
}
_modlistIterator = -1;
}
bool LocalModList::modDescriptionsAtEnd() {
return _modlistAtEnd;
}
void LocalModList::setConfigFile(ConfigFile conf) {
_conf = conf;
}
void LocalModList::write() {
std::ofstream lmfile(_conf.getModList().c_str());
if(!lmfile) {
lmfile.close();
throw FileException(_conf.getModList(), "writing", "Could not open file!");
}
for(unsigned int i = 0; i < _modlist.size(); i++) {
lmfile << "{" << _modlist[i].getName() << "}" << std::endl << "[rmodlist]" << std::endl << _modlist[i].getRemoteModlistName() << std::endl << "[description]" << std::endl << _modlist[i].getDescription() << std::endl << "[release]" << std::endl << _modlist[i].getReleaseNr() << std::endl << "[deps]" << std::endl;
_modlist[i].resetDependencyIterator();
while(!_modlist[i].dependenciesEnd()) {
std::string dep = _modlist[i].getNextDependency();
if(dep != "") {
lmfile << dep << std::endl;
}
}
lmfile << "[depsend]" << std::endl << "[repotype]" << std::endl << _modlist[i].getRepositoryType() << std::endl << "[repoaddr]" << std::endl << _modlist[i].getRepositoryAddress() << std::endl << "{end}" << std::endl;
}
lmfile.close();
}

46
LocalModList.h Normal file
View File

@ -0,0 +1,46 @@
#ifndef _LOCALMODLIST_H
#define _LOCALMODLIST_H
#include <string>
#include <vector>
#include "LocalModDescription.h"
#include "ConfigFile.h"
/// \file LocalModList.h
/// \brief A class representing a local modlist.
/// \author Phitherek_
/// \date 2013
/// \version 0.1-pre
/// \namespace mmm
/// \brief A global namespace for 3m.
namespace mmm {
/// \class LocalModList
/// \brief A class representing a local modlist.
class LocalModList {
private:
ConfigFile _conf;
std::vector<LocalModDescription> _modlist;
int _modlistIterator;
bool _modlistAtEnd;
public:
LocalModList(); ///< A constructor.
LocalModList(ConfigFile conf); ///< \brief A constructor with parameter.
///< This constructor tries to parse the modlist in the path given by the ConfigFile object.
///< \param conf A ConfigFile object.
~LocalModList(); ///< A destructor.
void addModDescription(LocalModDescription lmd); ///< \brief A function that adds a mod description to the modlist.
/// \param lmd A mod description to be added.
LocalModDescription getNextModDescription(); ///< \brief A function that returns next mod description from the modlist.
///< \return Next mod description from the modlist.
LocalModDescription getModDescriptionByName(std::string name); ///< \brief A function, that searches a mod name and returns its description.
///< \param name A mod name.
///< \return Description of the mod.
void resetModDescriptionIterator(); ///< A function that resets iterator of the modlist.
bool modDescriptionsAtEnd(); ///< \brief A function that returns if the modlist iterator has reached its end.
///< \return True if modlist iterator is at end, false otherwise.
void setConfigFile(ConfigFile conf); ///< \brief A function that sets the used config file.
///< \param conf A ConfigFile object.
void write(); ///< A function that writes the changes to the modlist file.
};
}
#endif

View File

@ -23,4 +23,4 @@ tests:
testsdebug:
make -C tests debug
testsclean:
make -C testsclean
make -C tests clean

View File

@ -9,6 +9,7 @@ ModDescription::ModDescription() {
_depsAtEnd = true;
_repotype = "";
_repoaddr = "";
_deps.clear();
}
ModDescription::~ModDescription() {
@ -20,6 +21,7 @@ ModDescription::~ModDescription() {
_depsAtEnd = true;
_repotype = "";
_repoaddr = "";
_deps.clear();
}
std::string ModDescription::getName() {
@ -89,3 +91,18 @@ void ModDescription::resetDependencyIterator() {
bool ModDescription::dependenciesEnd() {
return _depsAtEnd;
}
bool ModDescription::dependenciesEmpty() {
return _deps.empty();
}
void ModDescription::clear() {
_name = "";
_description = "";
_release = 0;
_depsIterator = -1;
_depsAtEnd = true;
_repotype = "";
_repoaddr = "";
_deps.clear();
}

View File

@ -53,6 +53,9 @@ public:
void resetDependencyIterator(); ///< A function resetting the iterator of the dependency list.
bool dependenciesEnd(); ///< \brief A function returning if dependency list is at its end.
///< \return True if dependency list iterator reached its end, false otherwise.
bool dependenciesEmpty(); ///< \brief A function returning if dependency list is empty.
///< \return True if dependency list is empty, false otherwise.
void clear(); ///< A function that clears the object.
};
}
#endif

View File

@ -37,3 +37,4 @@ public:
///< \param path Modinfo path on server.
};
}
#endif

View File

@ -1,6 +1,6 @@
ModDescription: name, description, release, deps, repotype, repoaddr x
ModList: ModListDescription, vector<ModInfoDescription>
ModListList: vector<ModListDescription>
ModListList: vector<ModListDescription> x
LocalModDescription: ModDescription + remoteModlist (inheritance) x
LocalModList: vector<LocalModDescription>, ConfigFile
RepositoryModDescription: ModDescription + path (inheritance) x

View File

@ -0,0 +1,67 @@
#include <iostream>
#include <cstdlib>
#include "../LocalModList.h"
#include "../3mExceptions.h"
using namespace std;
int main() {
string home = getenv("HOME");
string conffn = home + "/.3m/config";
try {
mmm::ConfigFile conf(conffn);
mmm::LocalModList lml(conf);
char action;
do {
cout << "Select action: (l)ist modlist, (f)ind and list mod by name, (s)ave and exit, (q)uit without saving: ";
cin >> action;
if(action == 'l') {
lml.resetModDescriptionIterator();
while(!lml.modDescriptionsAtEnd()) {
mmm::LocalModDescription temp;
temp = lml.getNextModDescription();
if(temp.getName() != "" && temp.getRemoteModlistName() != "" && temp.getDescription() != "" && !temp.dependenciesEmpty() && temp.getRepositoryType() != "" && temp.getRepositoryAddress() != "") {
cout << "name: " << temp.getName() << endl << "remote modlist name: " << temp.getRemoteModlistName() << endl << "description: " << temp.getDescription() << endl << "release: " << temp.getReleaseNr() << endl << "dependencies: " << endl;
temp.resetDependencyIterator();
while(!temp.dependenciesEnd()) {
string dep = temp.getNextDependency();
if(dep != "") {
cout << dep << endl;
}
}
cout << "repository type: " << temp.getRepositoryType() << endl << "repository address: " << temp.getRepositoryAddress() << endl;
}
}
cout << endl;
} else if(action == 'f') {
cout << "Enter name: ";
string name;
cin >> name;
mmm::LocalModDescription temp;
temp = lml.getModDescriptionByName(name);
if(temp.getName() != "" && temp.getRemoteModlistName() != "" && temp.getDescription() != "" && !temp.dependenciesEmpty() && temp.getRepositoryType() != "" && temp.getRepositoryAddress() != "") {
cout << "name: " << temp.getName() << endl << "remote modlist name: " << temp.getRemoteModlistName() << endl << "description: " << temp.getDescription() << endl << "release: " << temp.getReleaseNr() << endl << "dependencies: " << endl;
temp.resetDependencyIterator();
while(!temp.dependenciesEnd()) {
string dep = temp.getNextDependency();
if(dep != "") {
cout << dep << endl;
}
}
cout << "repository type: " << temp.getRepositoryType() << endl << "repository address: " << temp.getRepositoryAddress() << endl;
} else {
cout << name << " not found!" << endl;
}
}
} while(action != 'q' && action != 's');
if(action == 's') {
lml.write();
}
} catch(mmm::FileException &exc) {
cerr << "FileException occured: " << exc.what() << endl;
return EXIT_FAILURE;
} catch(mmm::ParseException &exc) {
cerr << "ParseException occured: " << exc.what() << endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}

View File

@ -4,10 +4,12 @@ all:
${CXX} ${CXXFLAGS} -o ModDescriptionTest ModDescriptionTest.cpp ../ModDescription.cpp
${CXX} ${CXXFLAGS} -o LocalModDescriptionTest LocalModDescriptionTest.cpp ../LocalModDescription.cpp ../ModDescription.cpp
${CXX} ${CXXFLAGS} -o ModListListTest ModListListTest.cpp ../ModListList.cpp ../ModListDescription.cpp ../3mExceptions.cpp
${CXX} ${CXXFLAGS} -o LocalModListTest LocalModListTest.cpp ../LocalModList.cpp ../LocalModDescription.cpp ../ModDescription.cpp ../3mExceptions.cpp ../ConfigFile.cpp
debug:
${CXX} ${CXXFLAGS} -o ConfigFileTest ConfigFileTest.cpp ../ConfigFile.cpp ../3mExceptions.cpp -g
${CXX} ${CXXFLAGS} -o ModDescriptionTest ModDescriptionTest.cpp ../ModDescription.cpp -g
${CXX} ${CXXFLAGS} -o LocalModDescriptionTest LocalModDescriptionTest.cpp ../LocalModDescription.cpp ../ModDescription.cpp
${CXX} ${CXXFLAGS} -o ModListListTest ModListListTest.cpp ../ModListList.cpp ../ModListDescription.cpp ../3mExceptions.cpp -g
${CXX} ${CXXFLAGS} -o LocalModListTest LocalModListTest.cpp ../LocalModList.cpp ../LocalModDescription.cpp ../ModDescription.cpp ../3mExceptions.cpp ../ConfigFile.cpp -g
clean:
rm -rf ConfigFileTest ModDescriptionTest LocalModDescriptionTest ModListListTest
rm -rf ConfigFileTest ModDescriptionTest LocalModDescriptionTest ModListListTest LocalModListTest