diff --git a/src/parser.cpp b/src/parser.cpp index d9efcdc..52bc768 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -99,7 +99,7 @@ namespace /* internal */ sign = -1; break; case '0' ... '9': - val = val*10 + *it_data; + val = val*10 + (*it_data - '0'); break; case '.': if(val == 0) @@ -177,8 +177,13 @@ namespace /* internal */ switch(*it_data) { case ',': - res.push_back( cur_tree->findId(name.data()) ); - name.clear(); + if(!name.empty()) + { + res.push_back( cur_tree->findId(name.data()) ); + name.clear(); + } + else + unexpected_char(','); break; case '\n': ++line; @@ -188,7 +193,9 @@ namespace /* internal */ name.push_back(*it_data); } } - /* return res;todo */ + if(!name.empty()) + res.push_back( cur_tree->findId(name.data()) ); + return res; } void state_neutral() @@ -216,7 +223,7 @@ namespace /* internal */ { char* name_start = it_data; pair parents(Nobody, Nobody); - person_id spouse; + vector spouses; EventTime birth{}; EventTime death{}; @@ -232,7 +239,8 @@ namespace /* internal */ { case '\n': ++line; - ++it_data; + break; + default: if(it_data[1] == ':') /* todo */ { switch(*it_data) @@ -251,7 +259,7 @@ namespace /* internal */ break; case 's': it_data += 2; - parseSpouses(); + spouses = parseSpouses(); break; default: unexpected_char(it_data[-1]); @@ -261,17 +269,17 @@ namespace /* internal */ else { cur_tree->addPerson(name.c_str(), sex, parents.first, parents.second, birth, death); + for(person_id spouse: spouses) + cur_tree->addRelation(spouse, Spouse, cur_tree->last()); + --it_data; /* rewind 1 */ return; } break; - /* case '#': */ - /* state = state_comment; */ - /* return; */ /* case 0...9: */ /* case ':': */ /* unexpected_char(*it_data); */ - default: - break; + /* default: */ + /* break; */ } } } @@ -308,7 +316,6 @@ namespace /* internal */ Tree parseTftFile(MappedFile file) { - Tree result("name"); cur_tree = &result; diff --git a/src/person.cpp b/src/person.cpp index 208301f..5ae4579 100644 --- a/src/person.cpp +++ b/src/person.cpp @@ -63,7 +63,7 @@ void EventTime::print() const Person::Person(const char* aName, EventTime birth, Sex aSex, EventTime death) : name(aName) , birth_(birth) - , sex(sex) + , sex(aSex) , death_(death) { } diff --git a/src/tft.cpp b/src/tft.cpp index c68929b..0225f7d 100644 --- a/src/tft.cpp +++ b/src/tft.cpp @@ -15,14 +15,14 @@ int main(int argc, char* argv[]) parseTftFile(f).display(); Tree test1("Dechkovi"); - test1.loadFromFile(); + /* test1.loadFromFile(); */ - /* test1.addPerson("Rumen", M, Nobody, Nobody, {1968, 8, 9}); */ - /* test1.addPerson("Nadejda", F, Nobody, Nobody, {1972, 12, 15}); */ - /* test1.addRelation(0, Spouse, 1); */ - /* test1.addPerson("Venelin", M, 0, 1, {1998, 6, 9}); */ - /* test1.addPerson("Vasil", M, 0, 1, {2001, 1, 16}); */ + test1.addPerson("Rumen", M, Nobody, Nobody, {1968, 8, 9}); + test1.addPerson("Nadejda", F, Nobody, Nobody, {1972, 12, 15}); + test1.addRelation(0, Spouse, 1); + test1.addPerson("Venelin", M, 0, 1, {1998, 6, 9}); + test1.addPerson("Vasil", M, 0, 1, {2001, 1, 16}); /* test1.saveToFile(); */ Tree test2("Karamanovi"); diff --git a/src/tree.cpp b/src/tree.cpp index 3f74495..dc2036a 100644 --- a/src/tree.cpp +++ b/src/tree.cpp @@ -18,12 +18,13 @@ Tree Tree::operator+ (const Tree& other) const Tree& Tree::operator+=(const Tree& other) { vector newId; //The indexes people from II tree will have in I tree - newId.reserve(other.numPeople); + newId.reserve(other.people.size()); - U32 idCounter = numPeople; - for (person_id i = 0, j; i < other.numPeople; ++i) //find the new ids for people in II, people present in both trees get the ids from I + U32 initNum = people.size(); /* number of people at the start */ + U32 idCounter = initNum; + for (person_id i = 0, j; i < other.people.size(); ++i) //find the new ids for people in II, people present in both trees get the ids from I { - for (j = 0; j < numPeople; ++j) + for (j = 0; j < initNum; ++j) { if (other.people[i] == people[j]) { @@ -31,21 +32,21 @@ Tree& Tree::operator+=(const Tree& other) break; } } - if (j >= numPeople) /* not present in I */ + if (j >= initNum) /* not present in I */ newId[i] = idCounter++; } people.reserve(idCounter); - for (person_id i = 0; i < other.numPeople; ++i) /* add the personal data of II to I */ + for (person_id i = 0; i < other.people.size(); ++i) /* add the personal data of II to I */ { - if (newId[i] >= numPeople) /* isnt already in I */ + if (newId[i] >= initNum) /* isnt already in I */ people.push_back(other.people[i]); } relations.reserve(idCounter); - for (person_id i = 0; i < other.numPeople; ++i) //merge the relative data + for (person_id i = 0; i < other.people.size(); ++i) //merge the relative data { - if (newId[i] >= numPeople) /* isnt already in I */ + if (newId[i] >= initNum) /* isnt already in I */ { relations.push_back(other.relations[i]); for (Relation& rel: relations.back()) @@ -57,7 +58,7 @@ Tree& Tree::operator+=(const Tree& other) { /* for (person_id j = 0; j < other.relations[i].size(); ++j) //combine relations */ /* { */ - /* if (newId[other.relations[i][j].id] >= numPeople) */ + /* if (newId[other.relations[i][j].id] >= initNum) */ /* ++people[newId[i]].numRel_; */ /* } */ person_id idIn1 = newId[i]; @@ -65,7 +66,7 @@ Tree& Tree::operator+=(const Tree& other) for (Relation rel: other.relations[i]) { - if(newId[rel.id] >= numPeople) /* not already in I */ + if(newId[rel.id] >= initNum) /* not already in I */ relations[idIn1].push_back( {newId[rel.id], rel.type} ); else { @@ -75,13 +76,12 @@ Tree& Tree::operator+=(const Tree& other) } } - numPeople = idCounter; //Number of members in I tree return *this; } Tree& Tree::operator-= (const Tree& other) { - for (U32 i = 0; i < numPeople; ++i) + for (U32 i = 0; i < people.size(); ++i) { for (const Person& othPers: other.people) { @@ -102,9 +102,14 @@ void Tree::rename(const char* newName) treeName = newName; } +person_id Tree::last() +{ + return people.size() - 1; +} + person_id Tree::findId(const char* name) const { - for (person_id i = 0; i < numPeople; ++i) + for (person_id i = 0; i < people.size(); ++i) { if (name == people[i].name) return i; @@ -115,7 +120,7 @@ person_id Tree::findId(const char* name) const person_id Tree::findId(const char* name, Sex s) const { Person sought(name, {}, s); - for (person_id i = 0; i < numPeople; ++i) + for (person_id i = 0; i < people.size(); ++i) { if (sought == people[i]) return i; @@ -135,14 +140,14 @@ person_id Tree::findOldestAncestor(person_id id, Sex sex) const person_id Tree::findCommonAncestor(const unsigned first, const unsigned second) const { - vector visited(numPeople); //if a member is visited twice he's a common ancestor + vector visited(people.size()); //if a member is visited twice he's a common ancestor commonAncestorRec(first, visited); commonAncestorRec(second, visited); person_id oldest = Nobody; U16 oldestBday = SHRT_MAX; - for (person_id i = 0; i < numPeople; ++i) + for (person_id i = 0; i < people.size(); ++i) { if (visited[i] == 2 && people[i].birth().year < oldestBday) { @@ -225,7 +230,8 @@ void Tree::saveToFile() const ofstream file(tftDir + '/' + treeName + ".tftb", std::ios::binary); - file.write((const char*)(&numPeople), sizeof(numPeople)); + U32 numPeople = people.size(); + file.write((const char*)(&numPeople), sizeof(people.size())); for (const Person& p: people) p.write(file); @@ -245,13 +251,14 @@ bool Tree::loadFromFile() ifstream file(tftDir + '/' + treeName + ".tftb", std::ios::binary); - file.read((char*)(&numPeople), sizeof(numPeople)); + U32 numPeople; + file.read((char*)(&numPeople), sizeof(people.size())); - people.resize(numPeople); + people.resize(people.size()); for (Person& p: people) p.read(file); - relations.resize(numPeople); + relations.resize(people.size()); for (auto& rels: relations) { U32 numRels; @@ -268,9 +275,8 @@ void Tree::addPerson(const char* name, Sex sex, unsigned father, unsigned mother people.emplace_back(name, birth, sex, death); relations.emplace_back(); /* relations of the new person */ - ++numPeople; - person_id new_person_id = numPeople - 1; + person_id new_person_id = people.size() - 1; addRelation(father, Parent, new_person_id); addRelation(mother, Parent, new_person_id); @@ -285,7 +291,7 @@ bool Tree::addRelation(const char* firstName, const RelType type, const char* se bool Tree::addRelation(const unsigned first, const RelType type, const unsigned second, bool update) { - if (first == Nobody || first >= numPeople || second == Nobody || second >= numPeople || type == None) + if (first == Nobody || first >= people.size() || second == Nobody || second >= people.size() || type == None) return false; switch (type) @@ -353,12 +359,12 @@ void Tree::removePerson(const person_id id) } } } - for (unsigned i = 0; i < relations[numPeople - 2].size(); ++i) //Move the last in his place and update IDs + for (unsigned i = 0; i < relations[people.size() - 2].size(); ++i) //Move the last in his place and update IDs { - relId = relations[numPeople - 1][i].id; + relId = relations[people.size() - 1][i].id; for (unsigned j = 0; j < relations[relId].size(); ++j) { - if (relations[relId][j].id == numPeople - 1) + if (relations[relId][j].id == people.size() - 1) { relations[relId][j].id = id; break; @@ -367,7 +373,6 @@ void Tree::removePerson(const person_id id) } remove(relations, id); remove(people, id); - --numPeople; } /* void Tree::removePerson(const char* personName, short year, unsigned char month, unsigned char day) */ diff --git a/src/tree.hpp b/src/tree.hpp index 5cb79d3..0c8f059 100644 --- a/src/tree.hpp +++ b/src/tree.hpp @@ -44,11 +44,13 @@ public: void rename(const char* newName); + person_id last(); person_id findId(const char* name) const; person_id findId(const char* name, Sex) const; person_id findOldestAncestor(person_id, Sex) const;// + //oldest common ancestor ID, a person is considerd an ancestor of himself - person_id findCommonAncestor(person_id first, person_id second) const; + person_id findCommonAncestor(person_id first, person_id second) const; /* needs to be fixed, never return nobody */ RelType findRelation(person_id first, person_id second) const; person_id findParent(person_id child, Sex parentSex) const; person_id findSpouse(person_id person) const; @@ -97,7 +99,6 @@ private: void selectRightSib(person_id); std::string treeName; - unsigned numPeople = 0; std::vector people; //The data for each member std::vector> relations; //The relatives of each member diff --git a/todo.txt b/todo.txt index 58badee..08aa276 100644 --- a/todo.txt +++ b/todo.txt @@ -1,9 +1,11 @@ + open tree Parser: - clean wh --help +help - lowercase findRelative