new tree file format

This commit is contained in:
vrd
2023-02-21 22:35:45 +02:00
parent ee152edbad
commit 78408bd223
11 changed files with 286 additions and 77 deletions
+39 -16
View File
@@ -1,30 +1,53 @@
void create_tree() void create_tree()
{ {
// Declare your tree // Declare your tree
Tree tree("first_tree"); Tree t("first_tree");
// Add member Adam with parents Nobody, Born: y, m, d // Add member Adam with parents Nobody
tree.addPerson("Адам", true, Nobody, Nobody, {0, 1, 6}); // ID 0 t.addPerson("Адам", M, // ID 0
tree.addPerson("Ева", false, Nobody, Nobody, {0, 1, 6}); // ID 1 Nobody, Nobody,
{0, 1, 6}); // Born: y, m, d
t.addPerson("Ева", F, // ID 1
Nobody, Nobody,
{0, 1, 6});
// Adam (0) is a Spouse of Eve (1) // Adam (0) is a Spouse of Eve (1)
tree.addRelation(0, Spouse, 1); t.addRelation(0, Spouse, 1);
// Add Cain with parents Adam (0) and Eve // Add Cain with parents Adam (0) and Eve
tree.addPerson("Кайн", true, 0, 1); t.addPerson("Кайн", M,
0, 1);
tree.addPerson("Авел", true, 0, 1); t.addPerson("Авел", M,
0, 1);
tree.addPerson("Сит", true, 0, 1, 230); t.addPerson("Сит", M,
tree.addPerson("Енос", true, 4, Nobody, 435); 0, 1,
tree.addPerson("Каинан", true, 5 , Nobody, 605); 230);
tree.addPerson("Малелеил", true, 6, Nobody, 605);
t.addPerson("Енос", M,
4, Nobody,
435);
t.addPerson("Каинан", M,
5, Nobody,
605);
t.addPerson("Малелеил", M,
6, Nobody,
605);
tree.addPerson("Енох", true, 3 , Nobody); t.addPerson("Енох", M,
tree.addPerson("Гаидад", true, 8 , Nobody); 3, Nobody);
tree.addPerson("Малелеил", true, 9, Nobody);
tree.saveToFile(); t.addPerson("Гаидад", M,
tree.display(); 8, Nobody);
t.addPerson("Малелеил", M,
9, Nobody);
/* t.saveToFile(); */
t.display();
} }
+157
View File
@@ -0,0 +1,157 @@
#include <iostream>
/* #include <string_view> */
#include <string>
#include "tree.hpp"
#include "utils.hpp"
using std::cerr;
using std::string_view;
using std::string;
namespace /* internal */
{
char* data;
char* data_end; /* past the end pointer */
unsigned line = 1;
/* state */
void (*state)(); /* current state */
void state_neutral();
void state_person();
/* void state_person_attribute() */
/* result */
Tree* cur_tree;
void unexpected_char(char c)
{
cerr << "Line " << line << ": Unexpected '" << c << "'\n";
exit(1);
/* throw 0; */
}
void unexpected_end()
{
cerr << "Unexpected end of file";
exit(1);
}
void proceedToNameEnd()
{
while(data < data_end &&
*data != ',' &&
*data != '\n')
{
if(*data == ':' /* && *data == '-' */)
unexpected_char(*data);
++data;
}
}
Sex findSex()
{
Sex res = M;
if(*data == ',')
{
++data;
if(*data == 'M')
res = M;
else if(*data == 'F')
res = F;
else
unexpected_char(*data);
++data;
if(*data != '\n')
unexpected_char(*data);
}
return res;
}
void processAtribute()
{
}
void state_neutral()
{
for(; data < data_end; ++data)
{
switch(*data)
{
default:
state_person();
return;
break;
case '\n':
++line;
break;
/* case '#': */
/* state = state_comment; */
/* return; */
case ',':
case '-':
case 0 ... 9:
case ':':
unexpected_char(*data);
}
}
}
void state_person()
{
char* name_start = data;
person_id parent1;
person_id parent2;
EventTime birth;
EventTime death;
proceedToNameEnd();
/* string_view name(name_start, data); */
string name(name_start, data);
Sex sex = findSex();
for(; data < data_end; ++data)
{
switch(*data)
{
case '\n':
++line;
if(data[1] == ':') /* todo */
{
processAtribute();
}
else
{
cur_tree->addPerson(name.c_str(), sex/* , parent1, parent2, birth, death */);
}
break;
/* case '#': */
/* state = state_comment; */
/* return; */
/* case 0...9: */
/* case ':': */
/* unexpected_char(*data); */
default:
break;
}
}
}
}
Tree parseTftFile(MappedFile file)
{
data = file.data;
data_end = file.data + file.len;
Tree result("name");
cur_tree = &result;
state_neutral();
return result;
}
+3
View File
@@ -0,0 +1,3 @@
#include "tree.hpp"
Tree parseTftFile(MappedFile file);
+6 -11
View File
@@ -60,10 +60,10 @@ void EventTime::print() const
} }
Person::Person(const char* name, EventTime birth, bool isMale, EventTime death) Person::Person(const char* name, EventTime birth, Sex sex, EventTime death)
: name_(name) : name_(name)
, birth_(birth) , birth_(birth)
, isMale_(isMale) , sex(sex)
, death_(death) , death_(death)
{ {
} }
@@ -71,7 +71,7 @@ Person::Person(const char* name, EventTime birth, bool isMale, EventTime death)
bool Person::operator==(const Person &other)const bool Person::operator==(const Person &other)const
{ {
return name_ == other.name_; //&& isMale_ == other.isMale_; //TODO && day == other.day || !day || !other.day) && (month == other.month || !month || !other.month) && (year == other.year || !year || !other.year); return name_ == other.name_; //&& sex == other.sex; //TODO && day == other.day || !day || !other.day) && (month == other.month || !month || !other.month) && (year == other.year || !year || !other.year);
} }
@@ -81,7 +81,7 @@ void Person::write(std::ofstream &file)const
char nameLen = name_.size(); char nameLen = name_.size();
file.write(reinterpret_cast<char*>(&nameLen), sizeof(nameLen)); file.write(reinterpret_cast<char*>(&nameLen), sizeof(nameLen));
file.write(name_.data(), nameLen * sizeof(name_[0])); file.write(name_.data(), nameLen * sizeof(name_[0]));
file.write(reinterpret_cast<const char*>(&isMale_), sizeof(isMale_)); file.write(reinterpret_cast<const char*>(&sex), sizeof(sex));
//file.write(reinterpret_cast<const char*>(&day), sizeof(day)); TODO //file.write(reinterpret_cast<const char*>(&day), sizeof(day)); TODO
//file.write(reinterpret_cast<const char*>(&month), sizeof(month)); //file.write(reinterpret_cast<const char*>(&month), sizeof(month));
//file.write(reinterpret_cast<const char*>(&year), sizeof(year)); //file.write(reinterpret_cast<const char*>(&year), sizeof(year));
@@ -97,7 +97,7 @@ void Person::read(std::ifstream &file)
nameBuf[nameLen] = '\0'; nameBuf[nameLen] = '\0';
name_ = nameBuf; name_ = nameBuf;
file.read(reinterpret_cast<char*>(&isMale_), sizeof(isMale_)); file.read(reinterpret_cast<char*>(&sex), sizeof(sex));
//file.read(reinterpret_cast<char*>(&day), sizeof(day)); TODO //file.read(reinterpret_cast<char*>(&day), sizeof(day)); TODO
//file.read(reinterpret_cast<char*>(&month), sizeof(month)); //file.read(reinterpret_cast<char*>(&month), sizeof(month));
//file.read(reinterpret_cast<char*>(&year), sizeof(year)); //file.read(reinterpret_cast<char*>(&year), sizeof(year));
@@ -132,11 +132,6 @@ void Person::displayInfo()const
} }
bool Person::isMale() const
{
return isMale_;
}
static U16 strUtf8Symbols(const std::string& str) static U16 strUtf8Symbols(const std::string& str)
{ {
U16 num = 0; U16 num = 0;
@@ -172,7 +167,7 @@ void Person::draw(const I16 drawY, const I16 drawX, bool selected, bool hasSpous
WINDOW* pad = newpad(BOX_HEIGHT, width); WINDOW* pad = newpad(BOX_HEIGHT, width);
auto color_pair = COLOR_PAIR( selected ? COLOR_SELECTED auto color_pair = COLOR_PAIR( selected ? COLOR_SELECTED
: (isMale_ ? COLOR_MALE : COLOR_FEMALE) ); : (sex ? COLOR_MALE : COLOR_FEMALE) );
wbkgd(pad, color_pair); wbkgd(pad, color_pair);
/* wattron(pad, color_pair); */ /* wattron(pad, color_pair); */
+5 -7
View File
@@ -20,10 +20,10 @@ struct EventTime
I8 minute; //0-59 I8 minute; //0-59
}; };
enum Genders: U8 enum Sex: U8
{ {
FEMALE = 0, M = 0,
MALE F
}; };
enum BoxColors: U8 { enum BoxColors: U8 {
@@ -41,7 +41,7 @@ class Person
{ {
public: public:
Person() = default; Person() = default;
Person(const char* name, EventTime birth={}, bool sex=true, EventTime death={}); Person(const char* name, EventTime birth={}, Sex=M, EventTime death={});
/* Person(Person&&) = default; */ /* Person(Person&&) = default; */
/* Person& operator=(Person&&) = default; */ /* Person& operator=(Person&&) = default; */
/* Person& operator=(const Person&) = default; */ /* Person& operator=(const Person&) = default; */
@@ -54,7 +54,6 @@ public:
void displayInfo() const; void displayInfo() const;
bool isMale() const;
const EventTime& birth() const { return birth_; }; const EventTime& birth() const { return birth_; };
U16 boxWidth() const; U16 boxWidth() const;
@@ -63,9 +62,8 @@ public:
returns the width of the box*/ returns the width of the box*/
void draw(I16 drawY, I16 drawX, bool selected, bool hasSpouse, bool isSpouse, bool hasChildren=false) const; void draw(I16 drawY, I16 drawX, bool selected, bool hasSpouse, bool isSpouse, bool hasChildren=false) const;
private:
std::string name_; std::string name_;
EventTime birth_; EventTime birth_;
bool isMale_; Sex sex;
EventTime death_; EventTime death_;
}; };
+27 -23
View File
@@ -2,6 +2,7 @@
#include <iostream> #include <iostream>
#include "tree.hpp" #include "tree.hpp"
#include "utils.hpp" #include "utils.hpp"
#include "parser.hpp"
/* using std::cin; */ /* using std::cin; */
@@ -10,27 +11,30 @@ int main(int argc, char* argv[])
{ {
init(); init();
auto f = mapfile("example_tree.tft");
parseTftFile(f).display();
Tree test1("Dechkovi"); Tree test1("Dechkovi");
test1.loadFromFile(); test1.loadFromFile();
/* test1.addPerson("Rumen", true, Nobody, Nobody, {1968, 8, 9}); */ /* test1.addPerson("Rumen", M, Nobody, Nobody, {1968, 8, 9}); */
/* test1.addPerson("Nadejda", false, Nobody, Nobody, {1972, 12, 15}); */ /* test1.addPerson("Nadejda", F, Nobody, Nobody, {1972, 12, 15}); */
/* test1.addRelation(0, Spouse, 1); */ /* test1.addRelation(0, Spouse, 1); */
/* test1.addPerson("Venelin", true, 0, 1, {1998, 6, 9}); */ /* test1.addPerson("Venelin", M, 0, 1, {1998, 6, 9}); */
/* test1.addPerson("Vasil", true, 0, 1, {2001, 1, 16}); */ /* test1.addPerson("Vasil", M, 0, 1, {2001, 1, 16}); */
/* test1.saveToFile(); */ /* test1.saveToFile(); */
Tree test2("Karamanovi"); Tree test2("Karamanovi");
test2.addPerson("Vasil Dimitrov", true, Nobody, Nobody, {1941, 5, 18}); test2.addPerson("Vasil Dimitrov", M, Nobody, Nobody, {1941, 5, 18});
test2.addPerson("Maria", false); test2.addPerson("Maria", F);
test2.addRelation(0, Spouse, 1); test2.addRelation(0, Spouse, 1);
test2.addPerson("Dimitar", true, 0, 1); test2.addPerson("Dimitar", M, 0, 1);
test2.addPerson("Nadejda", false, 0, 1, {1972, 12, 15}); test2.addPerson("Nadejda", F, 0, 1, {1972, 12, 15});
test2.addPerson("Branimira", false); test2.addPerson("Branimira", F);
test2.addRelation(2, Spouse, 4); test2.addRelation(2, Spouse, 4);
test2.addPerson("Ioan", true, 2, 4); test2.addPerson("Ioan", M, 2, 4);
test2.addPerson("Rumiana", false, 2, 4); test2.addPerson("Rumiana", F, 2, 4);
test1.display(); test1.display();
test2.display(); test2.display();
@@ -38,25 +42,25 @@ int main(int argc, char* argv[])
(test2 + test1).display(); (test2 + test1).display();
/* Tree firstTree("firstTree"); */ /* Tree firstTree("firstTree"); */
/* firstTree.addPerson("Адам", true, Nobody, Nobody, {0, 1, 6}); */ /* firstTree.addPerson("Адам", M, Nobody, Nobody, {0, 1, 6}); */
/* firstTree.addPerson("Ева", false, Nobody, Nobody, {0, 1, 6}); */ /* firstTree.addPerson("Ева", F, Nobody, Nobody, {0, 1, 6}); */
/* firstTree.addRelation(0, Spouse, 1); */ /* firstTree.addRelation(0, Spouse, 1); */
/* firstTree.addPerson("Кайн", true, 0, 1); */ /* firstTree.addPerson("Кайн", M, 0, 1); */
/* firstTree.addPerson("Авел", true, 0, 1); */ /* firstTree.addPerson("Авел", M, 0, 1); */
/* firstTree.addRelation(2, Sibling, 3); */ /* firstTree.addRelation(2, Sibling, 3); */
/* firstTree.addPerson("Сит", true, 0, 1, 230); */ /* firstTree.addPerson("Сит", M, 0, 1, 230); */
/* firstTree.addRelation(2, Sibling, 4); */ /* firstTree.addRelation(2, Sibling, 4); */
/* firstTree.addPerson("Енос", true, 4, Nobody, 435); */ /* firstTree.addPerson("Енос", M, 4, Nobody, 435); */
/* firstTree.addPerson("Каинан", true, 5 , Nobody, 605); */ /* firstTree.addPerson("Каинан", M, 5 , Nobody, 605); */
/* firstTree.addPerson("Малелеил", true, 6, Nobody, 605); */ /* firstTree.addPerson("Малелеил", M, 6, Nobody, 605); */
/* firstTree.addPerson("Енох", true, 3 , Nobody); */ /* firstTree.addPerson("Енох", M, 3 , Nobody); */
/* firstTree.addPerson("Гаидад", true, 8 , Nobody); */ /* firstTree.addPerson("Гаидад", M, 8 , Nobody); */
/* firstTree.addPerson("Малелеил", true, 9, Nobody); */ /* firstTree.addPerson("Малелеил", M, 9, Nobody); */
/* firstTree.print(); */ /* firstTree.print(); */
@@ -70,7 +74,7 @@ int main(int argc, char* argv[])
/* std::vector<Tree> trees; */ /* std::vector<Tree> trees; */
/* bool quit = false; */ /* bool quit = F; */
/* char input[128]; */ /* char input[128]; */
/* short i; //Number of the entered command */ /* short i; //Number of the entered command */
/* const short numCom = 24; */ /* const short numCom = 24; */
+16 -16
View File
@@ -102,9 +102,9 @@ void Tree::rename(const char* newName)
treeName = newName; treeName = newName;
} }
person_id Tree::findId(const char* name, bool m) const person_id Tree::findId(const char* name, Sex s) const
{ {
Person sought(name, {}, m); Person sought(name, {}, s);
for (person_id i = 0; i < numPeople; ++i) for (person_id i = 0; i < numPeople; ++i)
{ {
if (sought == people[i]) if (sought == people[i])
@@ -113,12 +113,12 @@ person_id Tree::findId(const char* name, bool m) const
return Nobody; return Nobody;
} }
person_id Tree::findOldestAncestor(person_id id, bool isMale) const person_id Tree::findOldestAncestor(person_id id, Sex sex) const
{ {
for (const Relation& rel: relations[id]) for (const Relation& rel: relations[id])
{ {
if (rel.type == Child && people[ rel.id ].isMale() == isMale) if (rel.type == Child && people[ rel.id ].sex == sex)
return findOldestAncestor(rel.id, isMale); return findOldestAncestor(rel.id, sex);
} }
return id; return id;
} }
@@ -143,12 +143,12 @@ person_id Tree::findCommonAncestor(const unsigned first, const unsigned second)
return oldest; return oldest;
} }
person_id Tree::findParent(person_id child, bool isParentMale) const person_id Tree::findParent(person_id child, Sex parentSex) const
{ {
person_id parent = Nobody; person_id parent = Nobody;
for(const Relation& rel: relations[child]) for(const Relation& rel: relations[child])
{ {
if (rel.type == Child && people[rel.id].isMale() == isParentMale) if (rel.type == Child && people[rel.id].sex == parentSex)
parent = rel.id; parent = rel.id;
} }
return parent; return parent;
@@ -253,9 +253,9 @@ bool Tree::loadFromFile()
return true; return true;
} }
void Tree::addPerson(const char* name, bool isMale, unsigned father, unsigned mother, EventTime birth, EventTime death) void Tree::addPerson(const char* name, Sex sex, unsigned father, unsigned mother, EventTime birth, EventTime death)
{ {
people.emplace_back(name, birth, isMale, death); people.emplace_back(name, birth, sex, death);
relations.emplace_back(); /* relations of the new person */ relations.emplace_back(); /* relations of the new person */
++numPeople; ++numPeople;
@@ -464,8 +464,8 @@ void Tree::display()
void Tree::updateRels(person_id id) void Tree::updateRels(person_id id)
{ {
person_id dad = findParent(id, true); person_id dad = findParent(id, M);
person_id mom = findParent(id, false); person_id mom = findParent(id, F);
auto dad_children = findChildren(dad, id); auto dad_children = findChildren(dad, id);
auto mom_children = findChildren(mom, id); auto mom_children = findChildren(mom, id);
@@ -570,8 +570,8 @@ void Tree::printMember(const unsigned id)const
void Tree::printOldestAncestors(const unsigned id)const void Tree::printOldestAncestors(const unsigned id)const
{ {
people[findOldestAncestor(id)].displayInfo(); people[findOldestAncestor(id, M)].displayInfo();
people[findOldestAncestor(id, 1)].displayInfo(); people[findOldestAncestor(id, F)].displayInfo();
} }
@@ -749,7 +749,7 @@ void Tree::selectUp()
{ {
if (rel.type == Child) if (rel.type == Child)
{ {
if (people[rel.id].isMale()) if (people[rel.id].sex == M)
dad = rel.id; dad = rel.id;
else else
mom = rel.id; mom = rel.id;
@@ -801,7 +801,7 @@ void Tree::selectLeftSibSpouse(person_id person) /* todo: return a value and spl
} }
} }
} }
else if(person_id sel_par = findParent(person, true); sel_par != Nobody) else if(person_id sel_par = findParent(person, M); sel_par != Nobody)
{ {
auto siblings = findChildren(sel_par); auto siblings = findChildren(sel_par);
for(auto it = siblings.begin()+1; it < siblings.end(); ++it) for(auto it = siblings.begin()+1; it < siblings.end(); ++it)
@@ -835,7 +835,7 @@ void Tree::selectRightSib(person_id person)
} }
} }
} }
else if(person_id sel_par = findParent(person, true); sel_par != Nobody) else if(person_id sel_par = findParent(person, M); sel_par != Nobody)
{ {
auto siblings = findChildren(sel_par); auto siblings = findChildren(sel_par);
for(auto it = siblings.begin(); it < siblings.end()-1; ++it) for(auto it = siblings.begin(); it < siblings.end()-1; ++it)
+5 -4
View File
@@ -44,12 +44,13 @@ public:
void rename(const char* newName); void rename(const char* newName);
person_id findId(const char* name, bool=true) const; person_id findId(const char* name) const{return Nobody;} /* todo */
person_id findOldestAncestor(person_id, bool sex = 0) 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 //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;
RelType findRelation(person_id first, person_id second) const; RelType findRelation(person_id first, person_id second) const;
person_id findParent(person_id child, bool isParentMale) const; person_id findParent(person_id child, Sex parentSex) const;
person_id findSpouse(person_id person) const; person_id findSpouse(person_id person) const;
std::vector<person_id> findChildren(person_id person) const; std::vector<person_id> findChildren(person_id person) const;
std::vector<person_id> findChildren(person_id person, person_id exclude) const; std::vector<person_id> findChildren(person_id person, person_id exclude) const;
@@ -57,7 +58,7 @@ public:
void saveToFile()const;// void saveToFile()const;//
bool loadFromFile(); bool loadFromFile();
void addPerson(const char* name, bool isMale, person_id father=Nobody, person_id mother=Nobody, EventTime birth={}, EventTime death={}); void addPerson(const char* name, Sex sex, person_id father=Nobody, person_id mother=Nobody, EventTime birth={}, EventTime death={});
bool addRelation(const char* firstName, RelType, const char* secondName); //Adds a new relation or edits an old one. 0 - failure 1 - success bool addRelation(const char* firstName, RelType, const char* secondName); //Adds a new relation or edits an old one. 0 - failure 1 - success
bool addRelation(person_id first, RelType, person_id second, bool update=true); //0 - failure 1 - success bool addRelation(person_id first, RelType, person_id second, bool update=true); //0 - failure 1 - success
+15
View File
@@ -1,6 +1,9 @@
#include "utils.hpp" #include "utils.hpp"
#include "person.hpp" #include "person.hpp"
#include <clocale> #include <clocale>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
void init() void init()
{ {
@@ -22,6 +25,18 @@ void init()
wnoutrefresh(stdscr); /* if not present the first real refresh is missed */ wnoutrefresh(stdscr); /* if not present the first real refresh is missed */
} }
MappedFile mapfile(const char* path)
{
int file = open(path, O_RDONLY);
MappedFile res;
res.len = lseek(file, 0, SEEK_END);
res.data = (char*)mmap(nullptr, res.len, PROT_READ, MAP_PRIVATE, file, 0);
close(file);
return res;
}
bool willBeVisible(I16 drawY, I16 drawX, U16 height, U16 width) bool willBeVisible(I16 drawY, I16 drawX, U16 height, U16 width)
{ {
return (drawY + height > 0) && (drawX + width > 0) && return (drawY + height > 0) && (drawX + width > 0) &&
+8
View File
@@ -25,6 +25,14 @@
void init(); void init();
struct MappedFile
{
char* data;
unsigned len;
};
MappedFile mapfile(const char* path);
template <class Vec> template <class Vec>
void remove(Vec& vec, size_t pos) /* Remove from vector by moving the last element in its place */ void remove(Vec& vec, size_t pos) /* Remove from vector by moving the last element in its place */
{ {
+5
View File
@@ -1,3 +1,8 @@
open tree
Parser:
- clean wh
--help --help
findRelative findRelative