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
+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)
, birth_(birth)
, isMale_(isMale)
, sex(sex)
, death_(death)
{
}
@@ -71,7 +71,7 @@ Person::Person(const char* name, EventTime birth, bool isMale, EventTime death)
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();
file.write(reinterpret_cast<char*>(&nameLen), sizeof(nameLen));
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*>(&month), sizeof(month));
//file.write(reinterpret_cast<const char*>(&year), sizeof(year));
@@ -97,7 +97,7 @@ void Person::read(std::ifstream &file)
nameBuf[nameLen] = '\0';
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*>(&month), sizeof(month));
//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)
{
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);
auto color_pair = COLOR_PAIR( selected ? COLOR_SELECTED
: (isMale_ ? COLOR_MALE : COLOR_FEMALE) );
: (sex ? COLOR_MALE : COLOR_FEMALE) );
wbkgd(pad, color_pair);
/* wattron(pad, color_pair); */
+5 -7
View File
@@ -20,10 +20,10 @@ struct EventTime
I8 minute; //0-59
};
enum Genders: U8
enum Sex: U8
{
FEMALE = 0,
MALE
M = 0,
F
};
enum BoxColors: U8 {
@@ -41,7 +41,7 @@ class Person
{
public:
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& operator=(Person&&) = default; */
/* Person& operator=(const Person&) = default; */
@@ -54,7 +54,6 @@ public:
void displayInfo() const;
bool isMale() const;
const EventTime& birth() const { return birth_; };
U16 boxWidth() const;
@@ -63,9 +62,8 @@ public:
returns the width of the box*/
void draw(I16 drawY, I16 drawX, bool selected, bool hasSpouse, bool isSpouse, bool hasChildren=false) const;
private:
std::string name_;
EventTime birth_;
bool isMale_;
Sex sex;
EventTime death_;
};
+27 -23
View File
@@ -2,6 +2,7 @@
#include <iostream>
#include "tree.hpp"
#include "utils.hpp"
#include "parser.hpp"
/* using std::cin; */
@@ -10,27 +11,30 @@ int main(int argc, char* argv[])
{
init();
auto f = mapfile("example_tree.tft");
parseTftFile(f).display();
Tree test1("Dechkovi");
test1.loadFromFile();
/* test1.addPerson("Rumen", true, Nobody, Nobody, {1968, 8, 9}); */
/* test1.addPerson("Nadejda", false, Nobody, Nobody, {1972, 12, 15}); */
/* 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", true, 0, 1, {1998, 6, 9}); */
/* test1.addPerson("Vasil", true, 0, 1, {2001, 1, 16}); */
/* test1.addPerson("Venelin", M, 0, 1, {1998, 6, 9}); */
/* test1.addPerson("Vasil", M, 0, 1, {2001, 1, 16}); */
/* test1.saveToFile(); */
Tree test2("Karamanovi");
test2.addPerson("Vasil Dimitrov", true, Nobody, Nobody, {1941, 5, 18});
test2.addPerson("Maria", false);
test2.addPerson("Vasil Dimitrov", M, Nobody, Nobody, {1941, 5, 18});
test2.addPerson("Maria", F);
test2.addRelation(0, Spouse, 1);
test2.addPerson("Dimitar", true, 0, 1);
test2.addPerson("Nadejda", false, 0, 1, {1972, 12, 15});
test2.addPerson("Branimira", false);
test2.addPerson("Dimitar", M, 0, 1);
test2.addPerson("Nadejda", F, 0, 1, {1972, 12, 15});
test2.addPerson("Branimira", F);
test2.addRelation(2, Spouse, 4);
test2.addPerson("Ioan", true, 2, 4);
test2.addPerson("Rumiana", false, 2, 4);
test2.addPerson("Ioan", M, 2, 4);
test2.addPerson("Rumiana", F, 2, 4);
test1.display();
test2.display();
@@ -38,25 +42,25 @@ int main(int argc, char* argv[])
(test2 + test1).display();
/* Tree firstTree("firstTree"); */
/* firstTree.addPerson("Адам", true, Nobody, Nobody, {0, 1, 6}); */
/* firstTree.addPerson("Ева", false, Nobody, Nobody, {0, 1, 6}); */
/* firstTree.addPerson("Адам", M, Nobody, Nobody, {0, 1, 6}); */
/* firstTree.addPerson("Ева", F, Nobody, Nobody, {0, 1, 6}); */
/* 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.addPerson("Сит", true, 0, 1, 230); */
/* firstTree.addPerson("Сит", M, 0, 1, 230); */
/* firstTree.addRelation(2, Sibling, 4); */
/* firstTree.addPerson("Енос", true, 4, Nobody, 435); */
/* firstTree.addPerson("Каинан", true, 5 , Nobody, 605); */
/* firstTree.addPerson("Малелеил", true, 6, Nobody, 605); */
/* firstTree.addPerson("Енос", M, 4, Nobody, 435); */
/* firstTree.addPerson("Каинан", M, 5 , Nobody, 605); */
/* firstTree.addPerson("Малелеил", M, 6, Nobody, 605); */
/* firstTree.addPerson("Енох", true, 3 , Nobody); */
/* firstTree.addPerson("Гаидад", true, 8 , Nobody); */
/* firstTree.addPerson("Малелеил", true, 9, Nobody); */
/* firstTree.addPerson("Енох", M, 3 , Nobody); */
/* firstTree.addPerson("Гаидад", M, 8 , Nobody); */
/* firstTree.addPerson("Малелеил", M, 9, Nobody); */
/* firstTree.print(); */
@@ -70,7 +74,7 @@ int main(int argc, char* argv[])
/* std::vector<Tree> trees; */
/* bool quit = false; */
/* bool quit = F; */
/* char input[128]; */
/* short i; //Number of the entered command */
/* const short numCom = 24; */
+16 -16
View File
@@ -102,9 +102,9 @@ void Tree::rename(const char* 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)
{
if (sought == people[i])
@@ -113,12 +113,12 @@ person_id Tree::findId(const char* name, bool m) const
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])
{
if (rel.type == Child && people[ rel.id ].isMale() == isMale)
return findOldestAncestor(rel.id, isMale);
if (rel.type == Child && people[ rel.id ].sex == sex)
return findOldestAncestor(rel.id, sex);
}
return id;
}
@@ -143,12 +143,12 @@ person_id Tree::findCommonAncestor(const unsigned first, const unsigned second)
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;
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;
}
return parent;
@@ -253,9 +253,9 @@ bool Tree::loadFromFile()
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 */
++numPeople;
@@ -464,8 +464,8 @@ void Tree::display()
void Tree::updateRels(person_id id)
{
person_id dad = findParent(id, true);
person_id mom = findParent(id, false);
person_id dad = findParent(id, M);
person_id mom = findParent(id, F);
auto dad_children = findChildren(dad, 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
{
people[findOldestAncestor(id)].displayInfo();
people[findOldestAncestor(id, 1)].displayInfo();
people[findOldestAncestor(id, M)].displayInfo();
people[findOldestAncestor(id, F)].displayInfo();
}
@@ -749,7 +749,7 @@ void Tree::selectUp()
{
if (rel.type == Child)
{
if (people[rel.id].isMale())
if (people[rel.id].sex == M)
dad = rel.id;
else
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);
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);
for(auto it = siblings.begin(); it < siblings.end()-1; ++it)
+5 -4
View File
@@ -44,12 +44,13 @@ public:
void rename(const char* newName);
person_id findId(const char* name, bool=true) const;
person_id findOldestAncestor(person_id, bool sex = 0) const;//
person_id findId(const char* name) const{return Nobody;} /* todo */
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;
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;
std::vector<person_id> findChildren(person_id person) const;
std::vector<person_id> findChildren(person_id person, person_id exclude) const;
@@ -57,7 +58,7 @@ public:
void saveToFile()const;//
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(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 "person.hpp"
#include <clocale>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
void init()
{
@@ -22,6 +25,18 @@ void init()
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)
{
return (drawY + height > 0) && (drawX + width > 0) &&
+8
View File
@@ -25,6 +25,14 @@
void init();
struct MappedFile
{
char* data;
unsigned len;
};
MappedFile mapfile(const char* path);
template <class Vec>
void remove(Vec& vec, size_t pos) /* Remove from vector by moving the last element in its place */
{