From ca3148b5cd938a9aadafa95b1a599516a0eba4ab Mon Sep 17 00:00:00 2001 From: Schombert Date: Fri, 16 Sep 2022 22:53:26 -0700 Subject: [PATCH] version 0.2 --- Catch_query_tests/Catch_query_tests.cpp | 89 +++ Catch_query_tests/query_objs.hpp | 598 ++++++++++++++++++ Catch_query_tests/query_objs.txt | 12 + .../DataContainerGenerator.cpp | 66 +- DataContainerGenerator/parsing.cpp | 487 +++++++------- DataContainerGenerator/parsing.hpp | 33 +- changes.md | 7 + file_format_documentation.md | 2 +- objects_and_properties.md | 3 + queries.md | 4 +- 10 files changed, 1041 insertions(+), 260 deletions(-) diff --git a/Catch_query_tests/Catch_query_tests.cpp b/Catch_query_tests/Catch_query_tests.cpp index 248a052..8828033 100644 --- a/Catch_query_tests/Catch_query_tests.cpp +++ b/Catch_query_tests/Catch_query_tests.cpp @@ -718,4 +718,93 @@ TEST_CASE("pairs of cars", "[query_tests]") { REQUIRE(cc); REQUIRE(cd); REQUIRE(count == 6); +} + +TEST_CASE("siblings test", "[query_tests]") { + auto ptr = std::make_unique(); + + auto gp1 = ptr->create_person(); + auto gp2 = ptr->create_person(); + auto gp3 = ptr->create_person(); + auto gp4 = ptr->create_person(); + auto gp5 = ptr->create_person(); + auto gp6 = ptr->create_person(); + auto gp7 = ptr->create_person(); + auto gp8 = ptr->create_person(); + auto gp9 = ptr->create_person(); + auto gp10 = ptr->create_person(); + + auto p1 = ptr->create_person(); + auto p2 = ptr->create_person(); + auto p3 = ptr->create_person(); + auto p4 = ptr->create_person(); + auto p5 = ptr->create_person(); + auto p6 = ptr->create_person(); + auto p7 = ptr->create_person(); + + auto c1 = ptr->create_person(); + auto c2 = ptr->create_person(); + auto c3 = ptr->create_person(); + auto c4 = ptr->create_person(); + auto c5 = ptr->create_person(); + auto c6 = ptr->create_person(); + auto c7 = ptr->create_person(); + auto c8 = ptr->create_person(); + + ptr->person_set_age(c1, 18); + ptr->person_set_age(c2, 20); + ptr->person_set_age(c3, 24); + ptr->person_set_age(c4, 28); + ptr->person_set_age(c5, 32); + ptr->person_set_age(c6, 44); + ptr->person_set_age(c7, 48); + ptr->person_set_age(c8, 54); + + ptr->person_set_wealth(c1, 1.8f); + ptr->person_set_wealth(c2, 20.0f); + ptr->person_set_wealth(c3, 24.0f); + ptr->person_set_wealth(c4, 2.8f); + ptr->person_set_wealth(c5, 0.32f); + ptr->person_set_wealth(c6, 4.4f); + ptr->person_set_wealth(c7, 48.0f); + ptr->person_set_wealth(c8, 5.4f); + + + ptr->try_create_parentage(c1, p1, p2); + ptr->try_create_parentage(c2, p1, p2); + + ptr->try_create_parentage(c3, p3, p4); + ptr->try_create_parentage(c4, p3, p4); + + ptr->try_create_parentage(c5, p5, p4); + + ptr->try_create_parentage(c6, p6, p7); + ptr->try_create_parentage(c7, p1, gp1); + ptr->try_create_parentage(c8, p5, gp2); + + ptr->try_create_parentage(p1, gp1, gp2); + ptr->try_create_parentage(p2, gp3, gp4); + ptr->try_create_parentage(p3, gp5, gp6); + ptr->try_create_parentage(p4, gp1, gp3); + ptr->try_create_parentage(p5, gp7, gp8); + ptr->try_create_parentage(p6, gp3, gp9); + ptr->try_create_parentage(p7, gp10, gp5); + + bool cb1 = false; + bool cb2 = false; + bool cb3 = false; + int32_t count = 0; + for(auto& q : ptr->query_siblings(p1)) { + ++count; + if(q.get_sibling_a_id() == c1 && q.get_sibling_b_id() == c2) + cb1 = true; + if(q.get_sibling_a_id() == c1 && q.get_sibling_b_id() == c7) + cb2 = true; + if(q.get_sibling_a_id() == c2 && q.get_sibling_b_id() == c7) + cb3 = true; + } + REQUIRE(count == 3); + REQUIRE(cb1); + REQUIRE(cb2); + REQUIRE(cb3); } \ No newline at end of file diff --git a/Catch_query_tests/query_objs.hpp b/Catch_query_tests/query_objs.hpp index 088265b..59281b7 100644 --- a/Catch_query_tests/query_objs.hpp +++ b/Catch_query_tests/query_objs.hpp @@ -451,6 +451,29 @@ namespace dcon { } }; + class query_siblings_iterator; + class query_siblings_const_iterator; + class query_siblings_instance { + public: + data_container& container; + person_id person_param; + query_siblings_instance(data_container& c , person_id p0) : container(c) , person_param(p0) {} + query_siblings_iterator begin(); + dcon::invalid_iterator_type end() const { + return dcon::invalid_iterator_type{}; + } + }; + class query_siblings_const_instance { + public: + data_container const& container; + person_id person_param; + query_siblings_const_instance(data_container const& c , person_id p0) : container(c) , person_param(p0) {} + query_siblings_const_iterator begin(); + dcon::invalid_iterator_type end() const { + return dcon::invalid_iterator_type{}; + } + }; + class alignas(64) car_class { private: // @@ -1989,6 +2012,10 @@ namespace dcon { friend internal::query_pairs_of_cars_iterator; internal::query_pairs_of_cars_instance query_pairs_of_cars() { return internal::query_pairs_of_cars_instance(*this); } internal::query_pairs_of_cars_const_instance query_pairs_of_cars() const { return internal::query_pairs_of_cars_const_instance(*this); } + friend internal::query_siblings_const_iterator; + friend internal::query_siblings_iterator; + internal::query_siblings_instance query_siblings(person_id person_param) { return internal::query_siblings_instance(*this, person_param); } + internal::query_siblings_const_instance query_siblings(person_id person_param) const { return internal::query_siblings_const_instance(*this, person_param); } void reset() { @@ -4296,6 +4323,115 @@ namespace dcon { query_pairs_of_cars_const_iterator query_pairs_of_cars_const_instance::begin() { return query_pairs_of_cars_const_iterator(container, *this); } + class query_siblings_instance; + class query_siblings_const_instance; + class query_siblings_iterator { + private: + data_container& m_container; + query_siblings_instance& m_parameters; + parentage_id m_tableindex1; + int32_t m_index_into_m_tableindex1 = 0; + int32_t m_size_of_m_tableindex1 = 0; + person_id m_tableindex2; + parentage_id m_tableindex3; + int32_t m_index_into_m_tableindex3 = 0; + int32_t m_size_of_m_tableindex3 = 0; + person_id m_tableindex4; + public: + query_siblings_iterator(data_container& c, query_siblings_instance& p) : m_container(c), m_parameters(p) { + internal_init(m_parameters.person_param); + } + auto operator++() -> query_siblings_iterator&; + bool operator==(dcon::invalid_iterator_type); + bool operator!=(dcon::invalid_iterator_type); + auto operator*() -> query_siblings_iterator const&; + private: + void internal_reset_aggregates(); + void internal_set_aggregates(); + void internal_update_aggregates(); + void internal_init(person_id first_value); + void internal_increment_to_result(bool); + void internal_reset_v0(); + bool internal_set_v0(person_id v); + bool internal_increment_v0(bool, bool&); + void internal_reset_v1(); + bool internal_set_v1(parentage_id v); + bool internal_increment_v1(bool force, bool& hit_group); + void internal_reset_v2(); + bool internal_set_v2(person_id v); + bool internal_increment_v2(bool force, bool& hit_group); + void internal_reset_v3(); + bool internal_set_v3(parentage_id v); + bool internal_increment_v3(bool force, bool& hit_group); + void internal_reset_v4(); + bool internal_set_v4(person_id v); + bool internal_increment_v4(bool force, bool& hit_group); + public: + person_fat_id get_base_id() const noexcept; + person_fat_id get_sibling_a_id() const noexcept; + person_fat_id get_sibling_b_id() const noexcept; + bool has_parentage() const noexcept; + bool has_sibling_a() const noexcept; + bool has_sibling_b() const noexcept; + + }; + class query_siblings_const_iterator { + private: + data_container const& m_container; + query_siblings_const_instance& m_parameters; + parentage_id m_tableindex1; + int32_t m_index_into_m_tableindex1 = 0; + int32_t m_size_of_m_tableindex1 = 0; + person_id m_tableindex2; + parentage_id m_tableindex3; + int32_t m_index_into_m_tableindex3 = 0; + int32_t m_size_of_m_tableindex3 = 0; + person_id m_tableindex4; + public: + query_siblings_const_iterator(data_container const& c, query_siblings_const_instance& p) : m_container(c), m_parameters(p) { + internal_init(m_parameters.person_param); + } + auto operator++() -> query_siblings_const_iterator&; + bool operator==(dcon::invalid_iterator_type); + bool operator!=(dcon::invalid_iterator_type); + auto operator*() -> query_siblings_const_iterator const&; + private: + void internal_reset_aggregates(); + void internal_set_aggregates(); + void internal_update_aggregates(); + void internal_init(person_id first_value); + void internal_increment_to_result(bool); + void internal_reset_v0(); + bool internal_set_v0(person_id v); + bool internal_increment_v0(bool, bool&); + void internal_reset_v1(); + bool internal_set_v1(parentage_id v); + bool internal_increment_v1(bool force, bool& hit_group); + void internal_reset_v2(); + bool internal_set_v2(person_id v); + bool internal_increment_v2(bool force, bool& hit_group); + void internal_reset_v3(); + bool internal_set_v3(parentage_id v); + bool internal_increment_v3(bool force, bool& hit_group); + void internal_reset_v4(); + bool internal_set_v4(person_id v); + bool internal_increment_v4(bool force, bool& hit_group); + public: + person_const_fat_id get_base_id() const noexcept; + person_const_fat_id get_sibling_a_id() const noexcept; + person_const_fat_id get_sibling_b_id() const noexcept; + bool has_parentage() const noexcept; + bool has_sibling_a() const noexcept; + bool has_sibling_b() const noexcept; + + }; + + query_siblings_iterator query_siblings_instance::begin() { + return query_siblings_iterator(container, *this); + } + query_siblings_const_iterator query_siblings_const_instance::begin() { + return query_siblings_const_iterator(container, *this); + } }; @@ -7525,6 +7661,468 @@ namespace dcon { return bool(m_tableindex4); } + auto internal::query_siblings_const_iterator::operator++() -> query_siblings_const_iterator& { + internal_increment_to_result(true); + return *this; + } + bool internal::query_siblings_const_iterator::operator==(dcon::invalid_iterator_type) { + return !bool(m_parameters.person_param); + } + bool internal::query_siblings_const_iterator::operator!=(dcon::invalid_iterator_type) { + return bool(m_parameters.person_param); + } + auto internal::query_siblings_const_iterator::operator*() -> query_siblings_const_iterator const& { + return *this; + } + void internal::query_siblings_const_iterator::internal_reset_aggregates() { + } + void internal::query_siblings_const_iterator::internal_set_aggregates() { + } + void internal::query_siblings_const_iterator::internal_update_aggregates() { + } + void internal::query_siblings_const_iterator::internal_init(person_id first_value) { + if(internal_set_v0(first_value)) { + if(m_tableindex2 .index() < m_tableindex4 .index()) { + return; + } + } + internal_increment_to_result(true); + } + void internal::query_siblings_const_iterator::internal_increment_to_result(bool) { + bool hit_group = false; + while(bool(m_parameters.person_param)) { + while(bool(m_parameters.person_param) && !internal_increment_v4(false, hit_group)) { + } + if(bool(m_parameters.person_param)) { + if(m_tableindex2 .index() < m_tableindex4 .index()) { + return; + } + } + } + } + void internal::query_siblings_const_iterator::internal_reset_v0() { + internal_reset_v1(); + internal_reset_v3(); + } + bool internal::query_siblings_const_iterator::internal_set_v0(person_id v) { + if(!bool(v)) { + return false; + } + return + [&](){ + auto range = m_container.person_range_of_parentage_as_bio_parent(m_parameters.person_param); + m_index_into_m_tableindex1 = 0; + m_size_of_m_tableindex1 = int32_t(range.second - range.first); + if(m_size_of_m_tableindex1 == 0) { + return internal_set_v1( parentage_id() ); + } else { + for( ; m_index_into_m_tableindex1 < m_size_of_m_tableindex1 ; ++ m_index_into_m_tableindex1) { + if(internal_set_v1( *(range.first + m_index_into_m_tableindex1) )) { + return true; + } + } + return false; + } + }() && + [&](){ + auto range = m_container.person_range_of_parentage_as_bio_parent(m_parameters.person_param); + m_index_into_m_tableindex3 = 0; + m_size_of_m_tableindex3 = int32_t(range.second - range.first); + if(m_size_of_m_tableindex3 == 0) { + return internal_set_v3( parentage_id() ); + } else { + for( ; m_index_into_m_tableindex3 < m_size_of_m_tableindex3 ; ++ m_index_into_m_tableindex3) { + if(internal_set_v3( *(range.first + m_index_into_m_tableindex3) )) { + return true; + } + } + return false; + } + }() && + true; + } + bool internal::query_siblings_const_iterator::internal_increment_v0(bool, bool&) { + m_parameters.person_param = person_id(); + return false; + } + void internal::query_siblings_const_iterator::internal_reset_v1() { + m_index_into_m_tableindex1 = 0; + m_size_of_m_tableindex1 = 0; + m_tableindex1 = parentage_id(); + internal_reset_v2(); + } + bool internal::query_siblings_const_iterator::internal_set_v1(parentage_id v) { + if(!bool(v)) { + m_tableindex1 = v; + return false; + } + m_tableindex1 = v; + return + [&](){ + return internal_set_v2( m_container.parentage_get_child(m_tableindex1) ); + }() && + [&](){ + auto range = m_container.person_range_of_parentage_as_bio_parent(m_parameters.person_param); + m_index_into_m_tableindex3 = 0; + m_size_of_m_tableindex3 = int32_t(range.second - range.first); + if(m_size_of_m_tableindex3 == 0) { + return internal_set_v3( parentage_id() ); + } else { + for( ; m_index_into_m_tableindex3 < m_size_of_m_tableindex3 ; ++ m_index_into_m_tableindex3) { + if(internal_set_v3( *(range.first + m_index_into_m_tableindex3) )) { + return true; + } + } + return false; + } + }() && + true; + } + bool internal::query_siblings_const_iterator::internal_increment_v1(bool force, bool& hit_group) { + if(!bool(m_tableindex1)) { + return internal_increment_v0(force, hit_group); + } + if(m_index_into_m_tableindex1 + 1 < m_size_of_m_tableindex1) { + ++m_index_into_m_tableindex1; + auto range = m_container.person_range_of_parentage_as_bio_parent(m_parameters.person_param); + return internal_set_v1( *(range.first + m_index_into_m_tableindex1) ); + } else { + m_tableindex1 = parentage_id(); + return internal_increment_v0(force, hit_group); + } + } + void internal::query_siblings_const_iterator::internal_reset_v2() { + m_tableindex2 = person_id(); + } + bool internal::query_siblings_const_iterator::internal_set_v2(person_id v) { + if(!bool(v)) { + m_tableindex2 = v; + return false; + } + m_tableindex2 = v; + return + [&](){ + auto range = m_container.person_range_of_parentage_as_bio_parent(m_parameters.person_param); + m_index_into_m_tableindex3 = 0; + m_size_of_m_tableindex3 = int32_t(range.second - range.first); + if(m_size_of_m_tableindex3 == 0) { + return internal_set_v3( parentage_id() ); + } else { + for( ; m_index_into_m_tableindex3 < m_size_of_m_tableindex3 ; ++ m_index_into_m_tableindex3) { + if(internal_set_v3( *(range.first + m_index_into_m_tableindex3) )) { + return true; + } + } + return false; + } + }() && + true; + } + bool internal::query_siblings_const_iterator::internal_increment_v2(bool force, bool& hit_group) { + if(!bool(m_tableindex2)) { + return internal_increment_v1(force, hit_group); + } + return internal_increment_v1(force, hit_group); + } + void internal::query_siblings_const_iterator::internal_reset_v3() { + m_index_into_m_tableindex3 = 0; + m_size_of_m_tableindex3 = 0; + m_tableindex3 = parentage_id(); + internal_reset_v4(); + } + bool internal::query_siblings_const_iterator::internal_set_v3(parentage_id v) { + if(!bool(v)) { + m_tableindex3 = v; + return false; + } + m_tableindex3 = v; + return + [&](){ + return internal_set_v4( m_container.parentage_get_child(m_tableindex3) ); + }() && + true; + } + bool internal::query_siblings_const_iterator::internal_increment_v3(bool force, bool& hit_group) { + if(!bool(m_tableindex3)) { + return internal_increment_v2(force, hit_group); + } + if(m_index_into_m_tableindex3 + 1 < m_size_of_m_tableindex3) { + ++m_index_into_m_tableindex3; + auto range = m_container.person_range_of_parentage_as_bio_parent(m_parameters.person_param); + return internal_set_v3( *(range.first + m_index_into_m_tableindex3) ); + } else { + m_tableindex3 = parentage_id(); + return internal_increment_v2(force, hit_group); + } + } + void internal::query_siblings_const_iterator::internal_reset_v4() { + m_tableindex4 = person_id(); + } + bool internal::query_siblings_const_iterator::internal_set_v4(person_id v) { + if(!bool(v)) { + m_tableindex4 = v; + return false; + } + m_tableindex4 = v; + return + true; + } + bool internal::query_siblings_const_iterator::internal_increment_v4(bool force, bool& hit_group) { + if(!bool(m_tableindex4)) { + return internal_increment_v3(force, hit_group); + } + return internal_increment_v3(force, hit_group); + } + person_const_fat_id internal::query_siblings_const_iterator::get_base_id() const noexcept { + return person_const_fat_id(m_container, m_parameters.person_param ); + } + person_const_fat_id internal::query_siblings_const_iterator::get_sibling_a_id() const noexcept { + return person_const_fat_id(m_container, m_tableindex2 ); + } + person_const_fat_id internal::query_siblings_const_iterator::get_sibling_b_id() const noexcept { + return person_const_fat_id(m_container, m_tableindex4 ); + } + bool internal::query_siblings_const_iterator::has_parentage() const noexcept { + return bool(m_tableindex1); + } + bool internal::query_siblings_const_iterator::has_sibling_a() const noexcept { + return bool(m_tableindex2); + } + bool internal::query_siblings_const_iterator::has_sibling_b() const noexcept { + return bool(m_tableindex4); + } + + auto internal::query_siblings_iterator::operator++() -> query_siblings_iterator& { + internal_increment_to_result(true); + return *this; + } + bool internal::query_siblings_iterator::operator==(dcon::invalid_iterator_type) { + return !bool(m_parameters.person_param); + } + bool internal::query_siblings_iterator::operator!=(dcon::invalid_iterator_type) { + return bool(m_parameters.person_param); + } + auto internal::query_siblings_iterator::operator*() -> query_siblings_iterator const& { + return *this; + } + void internal::query_siblings_iterator::internal_reset_aggregates() { + } + void internal::query_siblings_iterator::internal_set_aggregates() { + } + void internal::query_siblings_iterator::internal_update_aggregates() { + } + void internal::query_siblings_iterator::internal_init(person_id first_value) { + if(internal_set_v0(first_value)) { + if(m_tableindex2 .index() < m_tableindex4 .index()) { + return; + } + } + internal_increment_to_result(true); + } + void internal::query_siblings_iterator::internal_increment_to_result(bool) { + bool hit_group = false; + while(bool(m_parameters.person_param)) { + while(bool(m_parameters.person_param) && !internal_increment_v4(false, hit_group)) { + } + if(bool(m_parameters.person_param)) { + if(m_tableindex2 .index() < m_tableindex4 .index()) { + return; + } + } + } + } + void internal::query_siblings_iterator::internal_reset_v0() { + internal_reset_v1(); + internal_reset_v3(); + } + bool internal::query_siblings_iterator::internal_set_v0(person_id v) { + if(!bool(v)) { + return false; + } + return + [&](){ + auto range = m_container.person_range_of_parentage_as_bio_parent(m_parameters.person_param); + m_index_into_m_tableindex1 = 0; + m_size_of_m_tableindex1 = int32_t(range.second - range.first); + if(m_size_of_m_tableindex1 == 0) { + return internal_set_v1( parentage_id() ); + } else { + for( ; m_index_into_m_tableindex1 < m_size_of_m_tableindex1 ; ++ m_index_into_m_tableindex1) { + if(internal_set_v1( *(range.first + m_index_into_m_tableindex1) )) { + return true; + } + } + return false; + } + }() && + [&](){ + auto range = m_container.person_range_of_parentage_as_bio_parent(m_parameters.person_param); + m_index_into_m_tableindex3 = 0; + m_size_of_m_tableindex3 = int32_t(range.second - range.first); + if(m_size_of_m_tableindex3 == 0) { + return internal_set_v3( parentage_id() ); + } else { + for( ; m_index_into_m_tableindex3 < m_size_of_m_tableindex3 ; ++ m_index_into_m_tableindex3) { + if(internal_set_v3( *(range.first + m_index_into_m_tableindex3) )) { + return true; + } + } + return false; + } + }() && + true; + } + bool internal::query_siblings_iterator::internal_increment_v0(bool, bool&) { + m_parameters.person_param = person_id(); + return false; + } + void internal::query_siblings_iterator::internal_reset_v1() { + m_index_into_m_tableindex1 = 0; + m_size_of_m_tableindex1 = 0; + m_tableindex1 = parentage_id(); + internal_reset_v2(); + } + bool internal::query_siblings_iterator::internal_set_v1(parentage_id v) { + if(!bool(v)) { + m_tableindex1 = v; + return false; + } + m_tableindex1 = v; + return + [&](){ + return internal_set_v2( m_container.parentage_get_child(m_tableindex1) ); + }() && + [&](){ + auto range = m_container.person_range_of_parentage_as_bio_parent(m_parameters.person_param); + m_index_into_m_tableindex3 = 0; + m_size_of_m_tableindex3 = int32_t(range.second - range.first); + if(m_size_of_m_tableindex3 == 0) { + return internal_set_v3( parentage_id() ); + } else { + for( ; m_index_into_m_tableindex3 < m_size_of_m_tableindex3 ; ++ m_index_into_m_tableindex3) { + if(internal_set_v3( *(range.first + m_index_into_m_tableindex3) )) { + return true; + } + } + return false; + } + }() && + true; + } + bool internal::query_siblings_iterator::internal_increment_v1(bool force, bool& hit_group) { + if(!bool(m_tableindex1)) { + return internal_increment_v0(force, hit_group); + } + if(m_index_into_m_tableindex1 + 1 < m_size_of_m_tableindex1) { + ++m_index_into_m_tableindex1; + auto range = m_container.person_range_of_parentage_as_bio_parent(m_parameters.person_param); + return internal_set_v1( *(range.first + m_index_into_m_tableindex1) ); + } else { + m_tableindex1 = parentage_id(); + return internal_increment_v0(force, hit_group); + } + } + void internal::query_siblings_iterator::internal_reset_v2() { + m_tableindex2 = person_id(); + } + bool internal::query_siblings_iterator::internal_set_v2(person_id v) { + if(!bool(v)) { + m_tableindex2 = v; + return false; + } + m_tableindex2 = v; + return + [&](){ + auto range = m_container.person_range_of_parentage_as_bio_parent(m_parameters.person_param); + m_index_into_m_tableindex3 = 0; + m_size_of_m_tableindex3 = int32_t(range.second - range.first); + if(m_size_of_m_tableindex3 == 0) { + return internal_set_v3( parentage_id() ); + } else { + for( ; m_index_into_m_tableindex3 < m_size_of_m_tableindex3 ; ++ m_index_into_m_tableindex3) { + if(internal_set_v3( *(range.first + m_index_into_m_tableindex3) )) { + return true; + } + } + return false; + } + }() && + true; + } + bool internal::query_siblings_iterator::internal_increment_v2(bool force, bool& hit_group) { + if(!bool(m_tableindex2)) { + return internal_increment_v1(force, hit_group); + } + return internal_increment_v1(force, hit_group); + } + void internal::query_siblings_iterator::internal_reset_v3() { + m_index_into_m_tableindex3 = 0; + m_size_of_m_tableindex3 = 0; + m_tableindex3 = parentage_id(); + internal_reset_v4(); + } + bool internal::query_siblings_iterator::internal_set_v3(parentage_id v) { + if(!bool(v)) { + m_tableindex3 = v; + return false; + } + m_tableindex3 = v; + return + [&](){ + return internal_set_v4( m_container.parentage_get_child(m_tableindex3) ); + }() && + true; + } + bool internal::query_siblings_iterator::internal_increment_v3(bool force, bool& hit_group) { + if(!bool(m_tableindex3)) { + return internal_increment_v2(force, hit_group); + } + if(m_index_into_m_tableindex3 + 1 < m_size_of_m_tableindex3) { + ++m_index_into_m_tableindex3; + auto range = m_container.person_range_of_parentage_as_bio_parent(m_parameters.person_param); + return internal_set_v3( *(range.first + m_index_into_m_tableindex3) ); + } else { + m_tableindex3 = parentage_id(); + return internal_increment_v2(force, hit_group); + } + } + void internal::query_siblings_iterator::internal_reset_v4() { + m_tableindex4 = person_id(); + } + bool internal::query_siblings_iterator::internal_set_v4(person_id v) { + if(!bool(v)) { + m_tableindex4 = v; + return false; + } + m_tableindex4 = v; + return + true; + } + bool internal::query_siblings_iterator::internal_increment_v4(bool force, bool& hit_group) { + if(!bool(m_tableindex4)) { + return internal_increment_v3(force, hit_group); + } + return internal_increment_v3(force, hit_group); + } + person_fat_id internal::query_siblings_iterator::get_base_id() const noexcept { + return person_fat_id(m_container, m_parameters.person_param ); + } + person_fat_id internal::query_siblings_iterator::get_sibling_a_id() const noexcept { + return person_fat_id(m_container, m_tableindex2 ); + } + person_fat_id internal::query_siblings_iterator::get_sibling_b_id() const noexcept { + return person_fat_id(m_container, m_tableindex4 ); + } + bool internal::query_siblings_iterator::has_parentage() const noexcept { + return bool(m_tableindex1); + } + bool internal::query_siblings_iterator::has_sibling_a() const noexcept { + return bool(m_tableindex2); + } + bool internal::query_siblings_iterator::has_sibling_b() const noexcept { + return bool(m_tableindex4); + } + } #undef DCON_RELEASE_INLINE diff --git a/Catch_query_tests/query_objs.txt b/Catch_query_tests/query_objs.txt index 2e6a838..668e28a 100644 --- a/Catch_query_tests/query_objs.txt +++ b/Catch_query_tests/query_objs.txt @@ -145,3 +145,15 @@ query{ person.join car_ownership join car as car_b} } +query{ + name{siblings} + parameters{ + person_param{person_id} + } + select{base.id, sibling_a.id, sibling_b.id + from @person_param as base, + join on bio_parent parentage, join on child person as sibling_a, + base.join on bio_parent parentage, join on child person as sibling_b + where @sibling_a.id .index() < @sibling_b.id .index() } +} + diff --git a/DataContainerGenerator/DataContainerGenerator.cpp b/DataContainerGenerator/DataContainerGenerator.cpp index edb5dcf..9ed501d 100644 --- a/DataContainerGenerator/DataContainerGenerator.cpp +++ b/DataContainerGenerator/DataContainerGenerator.cpp @@ -15,14 +15,13 @@ -[[noreturn]] void error_to_file(std::string const& file_name, std::string const& message) { + void error_to_file(std::string const& file_name) { std::fstream fileout; fileout.open(file_name, std::ios::out); if(fileout.is_open()) { - fileout << message; + fileout << ""; fileout.close(); } - std::abort(); } relationship_object_def const* better_primary_key(relationship_object_def const* oldr, relationship_object_def const* newr) { @@ -78,6 +77,7 @@ relationship_object_def const* better_primary_key(relationship_object_def const* int main(int argc, char *argv[]) { if(argc > 1) { std::fstream input_file; + std::string input_file_name(argv[1]); input_file.open(argv[1], std::ios::in); const std::string output_file_name = [otemp = std::string(argv[1])]() mutable { @@ -90,13 +90,17 @@ int main(int argc, char *argv[]) { return otemp + ".cpp"; }(); + error_record err(input_file_name); if(!input_file.is_open()) { - error_to_file(output_file_name, std::string("Could not open input file: ") + argv[1]); + err.add(row_col_pair{ 0,0 }, 1000, "Could not open input file"); + error_to_file(output_file_name); + std::cout << err.accumulated; + return -1; } - error_record err; + std::string file_contents((std::istreambuf_iterator(input_file)), std::istreambuf_iterator()); @@ -104,8 +108,11 @@ int main(int argc, char *argv[]) { input_file.close(); - if(err.accumulated.length() > 0) - error_to_file(output_file_name, err.accumulated); + if(err.accumulated.length() > 0) { + error_to_file(output_file_name); + std::cout << err.accumulated; + return -1; + } // patchup relationship pointers & other information @@ -115,7 +122,10 @@ int main(int argc, char *argv[]) { if(auto linked_object = find_by_name(parsed_file, l.type_name); linked_object) { l.related_to = linked_object; } else { - error_to_file(output_file_name, std::string("Could not find object named: ") + l.type_name + " in relationship: " + r.name); + err.add(row_col_pair{ 0,0 }, 1001, std::string("Could not find object named: ") + l.type_name + " in relationship: " + r.name); + error_to_file(output_file_name); + std::cout << err.accumulated; + return -1; } if(l.index == index_type::at_most_one && !l.is_optional && l.multiplicity == 1) { r.primary_key.points_to = better_primary_key(r.primary_key.points_to, l.related_to); @@ -124,8 +134,11 @@ int main(int argc, char *argv[]) { } if(l.multiplicity > 1 && l.index == index_type::many && l.ltype == list_type::list) { - error_to_file(output_file_name, std::string("Unsupported combination of list type storage with multiplicity > 1 in link ") + err.add(row_col_pair{ 0,0 }, 1002, std::string("Unsupported combination of list type storage with multiplicity > 1 in link ") + l.property_name + " in relationship: " + r.name); + error_to_file(output_file_name); + std::cout << err.accumulated; + return -1; } if(l.multiplicity > 1 && l.index == index_type::at_most_one) { @@ -136,7 +149,10 @@ int main(int argc, char *argv[]) { if(r.indexed_objects.size() == 0) { - error_to_file(output_file_name, std::string("Relationship: ") + r.name + " is between too few objects"); + err.add(row_col_pair{ 0,0 }, 1003, std::string("Relationship: ") + r.name + " is between too few objects"); + error_to_file(output_file_name); + std::cout << err.accumulated; + return -1; } @@ -151,7 +167,10 @@ int main(int argc, char *argv[]) { } } if(!pk_forced) { - error_to_file(output_file_name, std::string("Was unable to use ") + r.force_pk + std::string(" as a primary key for relationship: ") + r.name); + err.add(row_col_pair{ 0,0 }, 1004, std::string("Was unable to use ") + r.force_pk + std::string(" as a primary key for relationship: ") + r.name); + error_to_file(output_file_name); + std::cout << err.accumulated; + return -1; } } @@ -171,9 +190,13 @@ int main(int argc, char *argv[]) { } } } else { - if(r.store_type != storage_type::erasable && r.store_type != storage_type::compactable) - error_to_file(output_file_name, std::string("Relationship ") + r.name + + if(r.store_type != storage_type::erasable && r.store_type != storage_type::compactable) { + err.add(row_col_pair{ 0,0 }, 1005, std::string("Relationship ") + r.name + " has no primary key, and thus must have either a compactable or erasable storage type to provide a delete function."); + error_to_file(output_file_name); + std::cout << err.accumulated; + return -1; + } } } // end if is a relationship @@ -232,8 +255,11 @@ int main(int argc, char *argv[]) { } if(k.object_type.length() == 0) { - error_to_file(output_file_name, std::string("Indexed link ") + k.property_name + " in composite key " + cc.name + + err.add(row_col_pair{ 0,0 }, 1006, std::string("Indexed link ") + k.property_name + " in composite key " + cc.name + " in relationship " + ob.name + " does not refer to a link in the relationship."); + error_to_file(output_file_name); + std::cout << err.accumulated; + return -1; } k.bit_position = bits_so_far; @@ -265,8 +291,11 @@ int main(int argc, char *argv[]) { for(auto& q : parsed_file.unprepared_queries) { parsed_file.prepared_queries.push_back(make_prepared_definition(parsed_file, q, err)); } - if(err.accumulated.length() > 0) - error_to_file(output_file_name, err.accumulated); + if(err.accumulated.length() > 0) { + error_to_file(output_file_name); + std::cout << err.accumulated; + return -1; + } // compose contents of generated file std::string output; @@ -467,8 +496,11 @@ int main(int argc, char *argv[]) { output += "\t\t\tdcon::stable_variable_vector_storage_mk_2<" + ob.name + "_id, 8, " + std::to_string(ob.size * 2) + " > " + i.property_name + "_storage;\n"; } else { - error_to_file(output_file_name, std::string("Unable to estimate an upper bound on storage space for ") + + err.add(row_col_pair{ 0,0 }, 1007, std::string("Unable to estimate an upper bound on storage space for ") + ob.name + " " + i.property_name + " arrays because the target is expandable"); + error_to_file(output_file_name); + std::cout << err.accumulated; + return -1; } } diff --git a/DataContainerGenerator/parsing.cpp b/DataContainerGenerator/parsing.cpp index 437132f..f4f103b 100644 --- a/DataContainerGenerator/parsing.cpp +++ b/DataContainerGenerator/parsing.cpp @@ -1,4 +1,5 @@ #include "parsing.hpp" +#include char const * advance_to_closing_bracket(char const * pos, char const * end) { int32_t depth_count = 0; @@ -192,8 +193,7 @@ std::vector parse_all_from_items(char const* &start, char const * end } if(result.size() == 0) { - err.add(std::string("a query must draw upon at least one data source, see line ") - + std::to_string(calculate_line_from_position(global_start, start_copy))); + err.add(calculate_line_from_position(global_start, start_copy), 1, std::string("a query must draw upon at least one data source")); } return result; @@ -244,11 +244,7 @@ from_item parse_from_item(char const* &start, char const * end, char const * glo result.type = from_type::parameter; ++start; - char const* id_start = advance_to_non_whitespace(start, end); - char const* id_end = advance_to_identifier_end(id_start, end); - - result.left_of_join = std::string(id_start, id_end); - start = id_end; + result.table_identifier = parse_qual_name(start, end, global_start, err); return result; } @@ -371,17 +367,22 @@ selection_item parse_selection_item(char const* &start, char const * end, char c return result; } -int32_t calculate_line_from_position(char const * start, char const * pos) { - int32_t line_count = 1; +row_col_pair calculate_line_from_position(char const * start, char const * pos) { + row_col_pair result; + result.row = 1; + result.column = 1; char const* t = start; while(t < pos) { - if(*t == '\n') - ++line_count; + if(*t == '\n') { + result.column = 0; + ++result.row; + } + ++result.column; ++t; } - return line_count; + return result; } parsed_item extract_item(char const * input, char const * end, char const * global_start, error_record & err) { @@ -399,7 +400,7 @@ parsed_item extract_item(char const * input, char const * end, char const * glob position = advance_to_non_whitespace(position + 1, end); char const* value_close = advance_to_closing_bracket(position, end); if(value_close == end) { - err.add(std::string("Open bracket on line ") + std::to_string(calculate_line_from_position(global_start, position)) + " was not properly closed."); + err.add(calculate_line_from_position(global_start, position), 2, "Open bracket was not properly closed."); } result.values.push_back(char_range{ position, reverse_to_non_whitespace(position, value_close) }); position = advance_to_non_whitespace(value_close + 1, end); @@ -420,62 +421,62 @@ load_save_def parse_load_save_def(char const* start, char const* end, char const std::string kstr = extracted.key.to_string(); if(kstr == "name") { if(extracted.values.size() != 1) { - err_out.add(std::string("wrong number of parameters for \"name\" on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 3, + std::string("wrong number of parameters for \"name\"")); } else { result.name = extracted.values[0].to_string(); } } else if(kstr == "only_objects") { if(extracted.values.size() == 0) { - err_out.add(std::string("wrong number of parameters for \"only_objects\" on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 4, + std::string("wrong number of parameters for \"only_objects\"")); } else if(result.objects_filter == filter_type::default_exclude) { result.objects_filter = filter_type::include; for(uint32_t i = 0; i < extracted.values.size(); ++ i) result.obj_tags.push_back(extracted.values[0].to_string()); } else { - err_out.add(std::string("illegal setting of the object filter a second time on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 5, + std::string("illegal setting of the object filter a second time")); } } else if(kstr == "exclude_objects") { if(extracted.values.size() == 0) { - err_out.add(std::string("wrong number of parameters for \"exclude_objects\" on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 6, + std::string("wrong number of parameters for \"exclude_objects\"")); } else if(result.objects_filter == filter_type::default_exclude) { result.objects_filter = filter_type::exclude; for(uint32_t i = 0; i < extracted.values.size(); ++i) result.obj_tags.push_back(extracted.values[0].to_string()); } else { - err_out.add(std::string("illegal setting of the object filter a second time on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 5, + std::string("illegal setting of the object filter a second time")); } } else if(kstr == "only_properties") { if(extracted.values.size() == 0) { - err_out.add(std::string("wrong number of parameters for \"only_properties\" on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 7, + std::string("wrong number of parameters for \"only_properties\"")); } else if(result.properties_filter == filter_type::default_exclude) { result.properties_filter = filter_type::include; for(uint32_t i = 0; i < extracted.values.size(); ++i) result.property_tags.push_back(extracted.values[0].to_string()); } else { - err_out.add(std::string("illegal setting of the properties filter a second time on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 8, + std::string("illegal setting of the properties filter a second time")); } } else if(kstr == "exclude_properties") { if(extracted.values.size() == 0) { - err_out.add(std::string("wrong number of parameters for \"exclude_properties\" on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 9, + std::string("wrong number of parameters for \"exclude_properties\"")); } else if(result.properties_filter == filter_type::default_exclude) { result.properties_filter = filter_type::exclude; for(uint32_t i = 0; i < extracted.values.size(); ++i) result.property_tags.push_back(extracted.values[0].to_string()); } else { - err_out.add(std::string("illegal setting of the properties filter a second time on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 8, + "illegal setting of the properties filter a second time on line "); } } else { - err_out.add(std::string("unexpected token \"") + kstr + "\" while parsing loading/saving routine defintion on line " - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 10, + std::string("unexpected token \"") + kstr + "\" while parsing loading/saving routine defintion"); } } } @@ -494,23 +495,23 @@ related_object parse_link_def(char const * start, char const * end, char const * std::string kstr = extracted.key.to_string(); if(kstr == "name") { if(extracted.values.size() != 1) { - err_out.add(std::string("wrong number of parameters for \"name\" on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 11, + std::string("wrong number of parameters for \"name\"")); } else { result.property_name = extracted.values[0].to_string(); } } else if(kstr == "type") { if(extracted.values.size() == 0 || extracted.values.size() > 2) { - err_out.add(std::string("wrong number of parameters for \"type\" on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 12, + std::string("wrong number of parameters for \"type\"")); } else if(extracted.values[0].to_string() == "unique") { result.index = index_type::at_most_one; if(extracted.values.size() > 1) { if(extracted.values[1].to_string() == "optional") { result.is_optional = true; } else { - err_out.add(std::string("unknown parameter \"") + extracted.values[1].to_string() + "\" passed to type on line " - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 13, + std::string("unknown parameter \"") + extracted.values[1].to_string() + "\" passed to type"); } } } else if(extracted.values[0].to_string() == "many") { @@ -519,8 +520,8 @@ related_object parse_link_def(char const * start, char const * end, char const * if(extracted.values[1].to_string() == "optional") { result.is_optional = true; } else { - err_out.add(std::string("unknown parameter \"") + extracted.values[1].to_string() + "\" passed to type on line " - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 13, + std::string("unknown parameter \"") + extracted.values[1].to_string() + "\" passed to type"); } } } else if(extracted.values[0].to_string() == "unindexed") { @@ -529,25 +530,25 @@ related_object parse_link_def(char const * start, char const * end, char const * if(extracted.values[1].to_string() == "optional") { result.is_optional = true; } else { - err_out.add(std::string("unknown parameter \"") + extracted.values[1].to_string() + "\" passed to type on line " - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 13, + std::string("unknown parameter \"") + extracted.values[1].to_string() + "\" passed to type"); } } } else { - err_out.add(std::string("unknown parameter \"") + extracted.values[0].to_string() + "\" passed to type on line " - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 14, + std::string("unknown parameter \"") + extracted.values[0].to_string() + "\" passed to type"); } } else if(kstr == "object") { if(extracted.values.size() != 1) { - err_out.add(std::string("wrong number of parameters for \"object\" on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 15, + std::string("wrong number of parameters for \"object\"")); } else { result.type_name = extracted.values[0].to_string(); } } else if(kstr == "index_storage") { if(extracted.values.size() != 1) { - err_out.add(std::string("wrong number of parameters for \"index_storage\" on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 16, + std::string("wrong number of parameters for \"index_storage\"")); } else if(extracted.values[0].to_string() == "std_vector") { result.ltype = list_type::std_vector; } else if(extracted.values[0].to_string() == "list") { @@ -555,47 +556,47 @@ related_object parse_link_def(char const * start, char const * end, char const * } else if(extracted.values[0].to_string() == "array") { result.ltype = list_type::array; } else { - err_out.add(std::string("unknown parameter \"") + extracted.values[0].to_string() + "\" passed to index_storage on line " - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 17, + std::string("unknown parameter \"") + extracted.values[0].to_string() + "\" passed to index_storage"); } } else if(kstr == "multiple") { if(extracted.values.size() != 1 && extracted.values.size() != 2) { - err_out.add(std::string("wrong number of parameters for \"multiple\" on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 18, + std::string("wrong number of parameters for \"multiple\"")); } else { result.multiplicity = std::stoi(extracted.values[0].to_string()); if(extracted.values.size() == 2) { if(extracted.values[1].to_string() == "distinct") { result.is_distinct = true; } else { - err_out.add(std::string("unknown parameter \"") + extracted.values[1].to_string() + "\" passed to multiple on line " - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 18, + std::string("unknown parameter \"") + extracted.values[1].to_string() + "\" passed to multiple"); } } } } else if(kstr == "private") { if(extracted.values.size() != 0) { - err_out.add(std::string("wrong number of parameters for \"private\" on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 19, + std::string("wrong number of parameters for \"private\"")); } else if(result.protection != protection_type::none) { - err_out.add(std::string("redefintion of access restriction on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 20, + std::string("redefintion of access restriction")); } else { result.protection = protection_type::hidden; } } else if(kstr == "protected") { if(extracted.values.size() != 0) { - err_out.add(std::string("wrong number of parameters for \"protected\" on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 21, + std::string("wrong number of parameters for \"protected\"")); } else if(result.protection != protection_type::none) { - err_out.add(std::string("redefintion of access restriction on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 20, + std::string("redefintion of access restriction")); } else { result.protection = protection_type::read_only; } } else { - err_out.add(std::string("unexpected token \"") + kstr + "\" while parsing link defintion on line " - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 22, + std::string("unexpected token \"") + kstr + "\" while parsing link defintion"); } } } @@ -614,21 +615,21 @@ composite_index_def parse_composite_key(char const * start, char const * end, ch std::string kstr = extracted.key.to_string(); if(kstr == "name") { if(extracted.values.size() != 1) { - err_out.add(std::string("wrong number of parameters for \"name\" on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 23, + std::string("wrong number of parameters for \"name\"")); } else { result.name = extracted.values[0].to_string(); } } else if(kstr == "index") { if(extracted.values.size() != 1) { - err_out.add(std::string("wrong number of parameters for \"index\" on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 24, + std::string("wrong number of parameters for \"index\"")); } else { result.component_indexes.push_back(key_component{ extracted.values[0].to_string(), std::string(), 0, 0 }); } } else { - err_out.add(std::string("unexpected token \"") + kstr + "\" while parsing composite key on line " - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 25, + std::string("unexpected token \"") + kstr + "\" while parsing composite key"); } } } @@ -647,15 +648,15 @@ property_def parse_property_def(char const * start, char const * end, char const std::string kstr = extracted.key.to_string(); if(kstr == "name") { if(extracted.values.size() != 1) { - err_out.add(std::string("wrong number of parameters for \"name\" on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 26, + std::string("wrong number of parameters for \"name\"")); } else { result.name = extracted.values[0].to_string(); } } else if(kstr == "type") { if(extracted.values.size() != 1) { - err_out.add(std::string("wrong number of parameters for \"type\" on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 27, + std::string("wrong number of parameters for \"type\"")); } else { auto inner_extracted = extract_item(extracted.values[0].start, extracted.values[0].end, global_start, err_out); std::string ikstr = inner_extracted.key.to_string(); @@ -664,16 +665,16 @@ property_def parse_property_def(char const * start, char const * end, char const result.type = property_type::bitfield; } else if(ikstr == "object") { if(inner_extracted.values.size() != 1) { - err_out.add(std::string("wrong number of parameters for \"object\" on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 28, + std::string("wrong number of parameters for \"object\"")); } else { result.type = property_type::object; result.data_type = inner_extracted.values[0].to_string(); } } else if(ikstr == "derived") { if(inner_extracted.values.size() != 1) { - err_out.add(std::string("wrong number of parameters for \"derived\" on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 29, + std::string("wrong number of parameters for \"derived\"")); } else { result.is_derived = true; if(inner_extracted.values[0].to_string() == "bitfield") @@ -684,8 +685,8 @@ property_def parse_property_def(char const * start, char const * end, char const } } else if(ikstr == "vector_pool") { if(inner_extracted.values.size() != 2) { - err_out.add(std::string("wrong number of parameters for \"vector_pool\" on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 30, + std::string("wrong number of parameters for \"vector_pool\"")); } else { result.type = property_type::special_vector; result.special_pool_size = std::stoi(inner_extracted.values[0].to_string()); @@ -693,8 +694,8 @@ property_def parse_property_def(char const * start, char const * end, char const } } else if(ikstr == "array") { if(inner_extracted.values.size() > 2) { - err_out.add(std::string("wrong number of parameters for \"array\" on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 31, + std::string("wrong number of parameters for \"array\"")); } else if(inner_extracted.values.size() == 2) { result.array_index_type = inner_extracted.values[0].to_string(); if(inner_extracted.values[1].to_string() == "bitfield") { @@ -714,8 +715,8 @@ property_def parse_property_def(char const * start, char const * end, char const } } else { if(inner_extracted.values.size() != 0) { - err_out.add(std::string("unexpected key \"" + ikstr + "\" on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 32, + std::string("unexpected key \"") + ikstr + "\""); } else { result.type = property_type::other; result.data_type = inner_extracted.key.to_string(); @@ -724,46 +725,46 @@ property_def parse_property_def(char const * start, char const * end, char const } } else if(kstr == "hook") { if(extracted.values.size() != 1) { - err_out.add(std::string("wrong number of parameters for \"hook\" on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 33, + std::string("wrong number of parameters for \"hook\"")); } else if(extracted.values[0].to_string() == "get") { result.hook_get = true; } else if(extracted.values[0].to_string() == "set") { result.hook_set = true; } else { - err_out.add(std::string("unknown parameter \"") + extracted.values[0].to_string() + "\" passed to hook on line " - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 34, + std::string("unknown parameter \"") + extracted.values[0].to_string() + "\" passed to hook"); } } else if(kstr == "tag") { if(extracted.values.size() != 1) { - err_out.add(std::string("wrong number of parameters for \"tag\" on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 35, + std::string("wrong number of parameters for \"tag\"")); } else { result.property_tags.push_back(extracted.values[0].to_string()); } } else if(kstr == "private") { if(extracted.values.size() != 0) { - err_out.add(std::string("wrong number of parameters for \"private\" on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 36, + std::string("wrong number of parameters for \"private\"")); } else if(result.protection != protection_type::none) { - err_out.add(std::string("redefintion of access restriction on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 37, + std::string("redefintion of access restriction")); } else { result.protection = protection_type::hidden; } } else if(kstr == "protected") { if(extracted.values.size() != 0) { - err_out.add(std::string("wrong number of parameters for \"protected\" on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 38, + std::string("wrong number of parameters for \"protected\"")); } else if(result.protection != protection_type::none) { - err_out.add(std::string("redefintion of access restriction on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 39, + std::string("redefintion of access restriction")); } else { result.protection = protection_type::read_only; } } else { - err_out.add(std::string("unexpected token \"") + kstr + "\" while parsing property defintion on line " - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 40, + std::string("unexpected token \"") + kstr + "\" while parsing property defintion"); } } } @@ -784,22 +785,22 @@ relationship_object_def parse_relationship(char const * start, char const * end, std::string kstr = extracted.key.to_string(); if(kstr == "name") { if(extracted.values.size() != 1) { - err_out.add(std::string("wrong number of parameters for \"name\" on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 41, + std::string("wrong number of parameters for \"name\"")); } else { result.name = extracted.values[0].to_string(); } } else if(kstr == "primary_key") { if(extracted.values.size() != 1) { - err_out.add(std::string("wrong number of parameters for \"primary_key\" on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 42, + std::string("wrong number of parameters for \"primary_key\"")); } else { result.force_pk = extracted.values[0].to_string(); } } else if(kstr == "storage_type") { if(extracted.values.size() != 1) { - err_out.add(std::string("wrong number of parameters for \"storage_type\" on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 43, + std::string("wrong number of parameters for \"storage_type\"")); } else { if(extracted.values[0].to_string() == "contiguous") { result.store_type = storage_type::contiguous; @@ -808,14 +809,14 @@ relationship_object_def parse_relationship(char const * start, char const * end, } else if(extracted.values[0].to_string() == "compactable") { result.store_type = storage_type::compactable; } else { - err_out.add(std::string("unknown parameter \"") + kstr + "\" passed to storage_type on line " - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 44, + std::string("unknown parameter \"") + kstr + "\" passed to storage_type"); } } } else if(kstr == "size") { if(extracted.values.size() != 1) { - err_out.add(std::string("wrong number of parameters for \"size\" on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 45, + std::string("wrong number of parameters for \"size\"")); } else { if(extracted.values[0].to_string() == "expandable") { result.is_expandable = true; @@ -827,39 +828,39 @@ relationship_object_def parse_relationship(char const * start, char const * end, } } else if(kstr == "tag") { if(extracted.values.size() != 1) { - err_out.add(std::string("wrong number of parameters for \"tag\" on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 46, + std::string("wrong number of parameters for \"tag\"")); } else { result.obj_tags.push_back(extracted.values[0].to_string()); } } else if(kstr == "property") { if(extracted.values.size() != 1) { - err_out.add(std::string("wrong number of parameters for \"property\" on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 47, + std::string("wrong number of parameters for \"property\"")); } else { result.properties.push_back( parse_property_def(extracted.values[0].start, extracted.values[0].end, global_start, err_out)); } } else if(kstr == "link") { if(extracted.values.size() != 1) { - err_out.add(std::string("wrong number of parameters for \"link\" on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 48, + std::string("wrong number of parameters for \"link\"")); } else { result.indexed_objects.push_back( parse_link_def(extracted.values[0].start, extracted.values[0].end, global_start, err_out)); } } else if(kstr == "composite_key") { if(extracted.values.size() != 1) { - err_out.add(std::string("wrong number of parameters for \"composite_key\" on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 49, + std::string("wrong number of parameters for \"composite_key\"")); } else { result.composite_indexes.push_back( parse_composite_key(extracted.values[0].start, extracted.values[0].end, global_start, err_out)); } } else if(kstr == "function") { if(extracted.values.size() != 1) { - err_out.add(std::string("wrong number of parameters for \"function\" on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 50, + std::string("wrong number of parameters for \"function\"")); } else { member_function_spec ns; ns.signature = remove_ats(extracted.values[0].start, extracted.values[0].end); @@ -879,8 +880,8 @@ relationship_object_def parse_relationship(char const * start, char const * end, } } else if(kstr == "const_function") { if(extracted.values.size() != 1) { - err_out.add(std::string("wrong number of parameters for \"const_function\" on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 51, + std::string("wrong number of parameters for \"const_function\"")); } else { member_function_spec ns; ns.signature = remove_ats(extracted.values[0].start, extracted.values[0].end); @@ -900,8 +901,8 @@ relationship_object_def parse_relationship(char const * start, char const * end, } } else if(kstr == "hook") { if(extracted.values.size() != 1) { - err_out.add(std::string("wrong number of parameters for \"hook\" on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 52, + std::string("wrong number of parameters for \"hook\"")); } else if(extracted.values[0].to_string() == "create") { result.hook_create = true; } else if(extracted.values[0].to_string() == "delete") { @@ -909,12 +910,12 @@ relationship_object_def parse_relationship(char const * start, char const * end, } else if(extracted.values[0].to_string() == "move") { result.hook_move = true; } else { - err_out.add(std::string("unknown parameter \"") + extracted.values[0].to_string() + "\" passed to hook on line " - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 53, + std::string("unknown parameter \"") + extracted.values[0].to_string() + "\" passed to hook"); } } else { - err_out.add(std::string("unexpected token \"") + kstr + "\" while parsing relationship defintion on line " - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 54, + std::string("unexpected token \"") + kstr + "\" while parsing relationship defintion"); } } } @@ -935,15 +936,15 @@ relationship_object_def parse_object(char const * start, char const * end, char std::string kstr = extracted.key.to_string(); if(kstr == "name") { if(extracted.values.size() != 1) { - err_out.add(std::string("wrong number of parameters for \"name\" on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 55, + std::string("wrong number of parameters for \"name\"")); } else { result.name = extracted.values[0].to_string(); } } else if(kstr == "storage_type") { if(extracted.values.size() != 1) { - err_out.add(std::string("wrong number of parameters for \"storage_type\" on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 56, + std::string("wrong number of parameters for \"storage_type\"")); } else { if(extracted.values[0].to_string() == "contiguous") { result.store_type = storage_type::contiguous; @@ -952,14 +953,14 @@ relationship_object_def parse_object(char const * start, char const * end, char } else if(extracted.values[0].to_string() == "compactable") { result.store_type = storage_type::compactable; } else { - err_out.add(std::string("unknown parameter \"") + kstr + "\" passed to storage_type on line " - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 57, + std::string("unknown parameter \"") + kstr + "\" passed to storage_type"); } } } else if(kstr == "size") { if(extracted.values.size() != 1) { - err_out.add(std::string("wrong number of parameters for \"size\" on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 58, + std::string("wrong number of parameters for \"size\"")); } else { if(extracted.values[0].to_string() == "expandable") { result.is_expandable = true; @@ -971,15 +972,15 @@ relationship_object_def parse_object(char const * start, char const * end, char } } else if(kstr == "tag") { if(extracted.values.size() != 1) { - err_out.add(std::string("wrong number of parameters for \"tag\" on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 59, + std::string("wrong number of parameters for \"tag\"")); } else { result.obj_tags.push_back(extracted.values[0].to_string()); } } else if(kstr == "hook") { if(extracted.values.size() != 1) { - err_out.add(std::string("wrong number of parameters for \"hook\" on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 60, + std::string("wrong number of parameters for \"hook\"")); } else if(extracted.values[0].to_string() == "create") { result.hook_create = true; } else if(extracted.values[0].to_string() == "delete") { @@ -987,21 +988,21 @@ relationship_object_def parse_object(char const * start, char const * end, char } else if(extracted.values[0].to_string() == "move") { result.hook_move = true; } else { - err_out.add(std::string("unknown parameter \"") + extracted.values[0].to_string() + "\" passed to hook on line " - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 61, + std::string("unknown parameter \"") + extracted.values[0].to_string() + "\" passed to hook"); } } else if(kstr == "property") { if(extracted.values.size() != 1) { - err_out.add(std::string("wrong number of parameters for \"property\" on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 62, + std::string("wrong number of parameters for \"property\"")); } else { result.properties.push_back( parse_property_def(extracted.values[0].start, extracted.values[0].end, global_start, err_out)); } } else if(kstr == "function") { if(extracted.values.size() != 1) { - err_out.add(std::string("wrong number of parameters for \"function\" on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 63, + std::string("wrong number of parameters for \"function\"")); } else { member_function_spec ns; ns.signature = remove_ats(extracted.values[0].start, extracted.values[0].end); @@ -1021,8 +1022,8 @@ relationship_object_def parse_object(char const * start, char const * end, char } } else if(kstr == "const_function") { if(extracted.values.size() != 1) { - err_out.add(std::string("wrong number of parameters for \"const_function\" on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 64, + std::string("wrong number of parameters for \"const_function\"")); } else { member_function_spec ns; ns.signature = remove_ats(extracted.values[0].start, extracted.values[0].end); @@ -1041,8 +1042,8 @@ relationship_object_def parse_object(char const * start, char const * end, char result.member_functions.push_back(ns); } } else { - err_out.add(std::string("unexpected token \"") + kstr + "\" while parsing relationship defintion on line " - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 65, + std::string("unexpected token \"") + kstr + "\" while parsing relationship defintion"); } } } @@ -1061,14 +1062,14 @@ std::vector parse_legacy_types(char const * start, char const * end std::string kstr = extracted.key.to_string(); if(kstr == "name") { if(extracted.values.size() != 1) { - err_out.add(std::string("wrong number of parameters for \"name\" on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 66, + std::string("wrong number of parameters for \"name\"")); } else { result.push_back(extracted.values[0].to_string()); } } else { - err_out.add(std::string("unexpected token \"") + kstr + "\" while parsing legacy types list on line " - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 67, + std::string("unexpected token \"") + kstr + "\" while parsing legacy types list"); } } } @@ -1086,27 +1087,27 @@ conversion_def parse_conversion_def(char const * start, char const * end, char c std::string kstr = extracted.key.to_string(); if(kstr == "from") { if(extracted.values.size() != 1) { - err_out.add(std::string("wrong number of parameters for \"from\" on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 68, + std::string("wrong number of parameters for \"from\"")); } else if(result.from.length() == 0) { result.from = extracted.values[0].to_string(); } else { - err_out.add(std::string("multiple defintion of \"from\" while parsing conversion defintion on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 69, + std::string("multiple defintion of \"from\" while parsing conversion defintion")); } } else if(kstr == "to") { if(extracted.values.size() != 1) { - err_out.add(std::string("wrong number of parameters for \"to\" on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 70, + std::string("wrong number of parameters for \"to\"")); } else if(result.to.length() == 0) { result.to = extracted.values[0].to_string(); } else { - err_out.add(std::string("multiple defintion of \"to\" while parsing conversion defintion on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 71, + std::string("multiple defintion of \"to\" while parsing conversion defintion")); } } else { - err_out.add(std::string("unexpected token \"") + kstr + "\" while parsing conversion defintion on line " - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err_out.add(calculate_line_from_position(global_start, extracted.key.start), 72, + std::string("unexpected token \"") + kstr + "\" while parsing conversion defintion"); } } } @@ -1125,12 +1126,11 @@ std::vector parse_query_parameters_list(char const* &start, char std::string kstr = extracted.key.to_string(); if(extracted.values.size() == 0) { - err.add(std::string("missing type declaration on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); - + err.add(calculate_line_from_position(global_start, extracted.key.start), 73, + std::string("missing type declaration")); } else if(extracted.values.size() > 1) { - err.add(std::string("too many type declarations on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err.add(calculate_line_from_position(global_start, extracted.key.start), 74, + std::string("too many type declarations")); } else { result.push_back(type_name_pair{ kstr, extracted.values[0].to_string() }); } @@ -1151,32 +1151,32 @@ query_definition parse_query_definition(char const* &start, char const * end, ch std::string kstr = extracted.key.to_string(); if(kstr == "name") { if(extracted.values.size() != 1) { - err.add(std::string("wrong number of parameters for \"name\" on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err.add(calculate_line_from_position(global_start, extracted.key.start), 75, + std::string("wrong number of parameters for \"name\"")); } else if(result.name.length() == 0) { result.name = extracted.values[0].to_string(); } else { - err.add(std::string("multiple defintion of \"name\" while parsing query defintion on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err.add(calculate_line_from_position(global_start, extracted.key.start), 76, + std::string("multiple defintion of \"name\" while parsing query defintion")); } } else if(kstr == "select") { if(extracted.values.size() != 1) { - err.add(std::string("wrong number of parameters for \"select\" on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err.add(calculate_line_from_position(global_start, extracted.key.start), 77, + std::string("wrong number of parameters for \"select\"")); } else { result.line = calculate_line_from_position(global_start, extracted.values[0].start); result.select = parse_select_statement(extracted.values[0].start, extracted.values[0].end, global_start, err); } } else if(kstr == "parameters") { if(extracted.values.size() != 1) { - err.add(std::string("wrong number of parameters for \"parameters\" on line ") - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err.add(calculate_line_from_position(global_start, extracted.key.start), 78, + std::string("wrong number of parameters for \"parameters\"")); } else { result.parameters = parse_query_parameters_list(extracted.values[0].start, extracted.values[0].end, global_start, err); } } else { - err.add(std::string("unexpected token \"") + kstr + "\" while parsing query defintion on line " - + std::to_string(calculate_line_from_position(global_start, extracted.key.start))); + err.add(calculate_line_from_position(global_start, extracted.key.start), 79, + std::string("unexpected token \"") + kstr + "\" while parsing query defintion"); } } } @@ -1195,30 +1195,30 @@ file_def parse_file(char const * start, char const * end, error_record & err_out std::string kstr(extracted.key.start, extracted.key.end); if(kstr == "namespace") { if(extracted.values.size() != 1) { - err_out.add(std::string("wrong number of parameters for \"namespace\" on line ") - + std::to_string(calculate_line_from_position(start, extracted.key.start))); + err_out.add(calculate_line_from_position(start, extracted.key.start), 80, + std::string("wrong number of parameters for \"namespace\"")); } else { parsed_file.namspace = extracted.values[0].to_string(); } } else if(kstr == "include") { if(extracted.values.size() != 1) { - err_out.add(std::string("wrong number of parameters for \"include\" on line ") - + std::to_string(calculate_line_from_position(start, extracted.key.start))); + err_out.add(calculate_line_from_position(start, extracted.key.start), 81, + std::string("wrong number of parameters for \"include\"")); } else { parsed_file.includes.push_back(extracted.values[0].to_string()); } } else if(kstr == "convert") { if(extracted.values.size() != 1) { - err_out.add(std::string("wrong number of parameters for \"convert\" on line ") - + std::to_string(calculate_line_from_position(start, extracted.key.start))); + err_out.add(calculate_line_from_position(start, extracted.key.start), 82, + std::string("wrong number of parameters for \"convert\"")); } else { parsed_file.conversion_list.push_back( parse_conversion_def(extracted.values[0].start, extracted.values[0].end, start, err_out)); } } else if(kstr == "legacy_types") { if(extracted.values.size() != 1) { - err_out.add(std::string("wrong number of parameters for \"legacy_types\" on line ") - + std::to_string(calculate_line_from_position(start, extracted.key.start))); + err_out.add(calculate_line_from_position(start, extracted.key.start), 83, + std::string("wrong number of parameters for \"legacy_types\"")); } else { auto nlist = parse_legacy_types(extracted.values[0].start, extracted.values[0].end, start, err_out); for(auto& s : nlist) { @@ -1227,53 +1227,53 @@ file_def parse_file(char const * start, char const * end, error_record & err_out } } else if(kstr == "global") { if(extracted.values.size() != 1) { - err_out.add(std::string("wrong number of parameters for \"global\" on line ") - + std::to_string(calculate_line_from_position(start, extracted.key.start))); + err_out.add(calculate_line_from_position(start, extracted.key.start), 84, + std::string("wrong number of parameters for \"global\"")); } else { parsed_file.globals.push_back(extracted.values[0].to_string()); } } else if(kstr == "make_index") { if(extracted.values.size() != 2) { - err_out.add(std::string("wrong number of parameters for \"make_index\" on line ") - + std::to_string(calculate_line_from_position(start, extracted.key.start))); + err_out.add(calculate_line_from_position(start, extracted.key.start), 85, + std::string("wrong number of parameters for \"make_index\"")); } else { parsed_file.extra_ids.push_back(made_id{ extracted.values[0].to_string() , extracted.values[1].to_string() }); } } else if(kstr == "load_save") { if(extracted.values.size() != 1) { - err_out.add(std::string("wrong number of parameters for \"load_save\" on line ") - + std::to_string(calculate_line_from_position(start, extracted.key.start))); + err_out.add(calculate_line_from_position(start, extracted.key.start), 86, + std::string("wrong number of parameters for \"load_save\"")); } else { parsed_file.load_save_routines.push_back( parse_load_save_def(extracted.values[0].start, extracted.values[0].end, start, err_out)); } } else if(kstr == "object") { if(extracted.values.size() != 1) { - err_out.add(std::string("wrong number of parameters for \"object\" on line ") - + std::to_string(calculate_line_from_position(start, extracted.key.start))); + err_out.add(calculate_line_from_position(start, extracted.key.start), 87, + std::string("wrong number of parameters for \"object\"")); } else { parsed_file.relationship_objects.push_back( parse_object(extracted.values[0].start, extracted.values[0].end, start, err_out)); } } else if(kstr == "relationship") { if(extracted.values.size() != 1) { - err_out.add(std::string("wrong number of parameters for \"relationship\" on line ") - + std::to_string(calculate_line_from_position(start, extracted.key.start))); + err_out.add(calculate_line_from_position(start, extracted.key.start), 88, + std::string("wrong number of parameters for \"relationship\"")); } else { parsed_file.relationship_objects.push_back( parse_relationship(extracted.values[0].start, extracted.values[0].end, start, err_out)); } } else if(kstr == "query") { if(extracted.values.size() != 1) { - err_out.add(std::string("wrong number of parameters for \"query\" on line ") - + std::to_string(calculate_line_from_position(start, extracted.key.start))); + err_out.add(calculate_line_from_position(start, extracted.key.start), 89, + std::string("wrong number of parameters for \"query\"")); } else { parsed_file.unprepared_queries.push_back( parse_query_definition(extracted.values[0].start, extracted.values[0].end, start, err_out)); } } else { - err_out.add(std::string("unexpetected top level key: ") + kstr + " on line " - + std::to_string(calculate_line_from_position(start, extracted.key.start))); + err_out.add(calculate_line_from_position(start, extracted.key.start), 90, + std::string("unexpetected top level key: ") + kstr); } } } @@ -1327,37 +1327,40 @@ prepared_query_definition make_prepared_definition(file_def const& parsed_file, if(result.table_slots[i].is_parameter_type) { if(i != 0) { - err.add(std::string("query on line ") + std::to_string(def.line) - + ": Only the first target in a from clause can be a parameter; use \"where\" to filter other targets"); + err.add(def.line, 91, "Only the first target in a from clause can be a parameter; use \"where\" to filter other targets"); + return result; } - result.table_slots[i].internally_named_as = std::string("m_parameters.") + def.select.from[i].left_of_join; - result.table_slots[i].reference_name = def.select.from[i].left_of_join; + result.table_slots[i].internally_named_as = std::string("m_parameters.") + def.select.from[i].table_identifier.member_name; + result.table_slots[i].reference_name = def.select.from[i].table_identifier.as_name; std::string param_id; for(auto &p : def.parameters) { - if(p.name == def.select.from[i].left_of_join) + if(p.name == def.select.from[i].table_identifier.member_name) param_id = p.type; } param_id.pop_back(); param_id.pop_back(); param_id.pop_back(); result.table_slots[i].actual_table = find_by_name(parsed_file, param_id); if(!result.table_slots[i].actual_table) { - err.add(std::string("Could not find an object or relationship named ") + err.add(def.line, 92, std::string("Could not find an object or relationship named ") + param_id + " as required by usage of parameter " - + def.select.from[i].left_of_join + " in a from clause"); + + def.select.from[i].table_identifier.member_name + " in a from clause"); + return result; } auto parameter = std::find_if(def.parameters.begin(), def.parameters.end(), - [&](type_name_pair const& p) { return def.select.from[i].left_of_join == p.name; }); + [&](type_name_pair const& p) { return def.select.from[i].table_identifier.member_name == p.name; }); if(parameter != def.parameters.end()) { std::string derived_type = parameter->type.substr(0, parameter->type.length() - 3); result.table_slots[i].actual_table = find_by_name(parsed_file, derived_type); if(!result.table_slots[i].actual_table) { - err.add(std::string("Could not find an object or relationship named ") + err.add(def.line, 93, std::string("Could not find an object or relationship named ") + derived_type + " as required by usage of parameter " - + def.select.from[i].left_of_join +" in a from clause"); + + def.select.from[i].table_identifier.member_name +" in a from clause"); + return result; } } else { - err.add(std::string("query on line ") + std::to_string(def.line) + - std::string(": Could not find query parameter refernced as ") - + def.select.from[i].left_of_join + " in from clause of a query in its the parameter list"); + err.add(def.line, 94, + std::string("Could not find query parameter refernced as ") + + def.select.from[i].table_identifier.member_name + " in from clause of a query in its the parameter list"); + return result; } } else { //first find base name @@ -1369,9 +1372,10 @@ prepared_query_definition make_prepared_definition(file_def const& parsed_file, result.table_slots[i].internally_named_as = std::string("m_tableindex") + std::to_string(i); result.table_slots[i].actual_table = find_by_name(parsed_file, def.select.from[i].table_identifier.member_name); if(!result.table_slots[i].actual_table) { - err.add(std::string("query on line ") + std::to_string(def.line) - + std::string(": Could not find an object or relationship named ") + err.add(def.line, 95, + std::string("Could not find an object or relationship named ") + def.select.from[i].table_identifier.member_name + " referenced in a from clause"); + return result; } if(def.select.from[i].left_of_join == "") { @@ -1385,30 +1389,34 @@ prepared_query_definition make_prepared_definition(file_def const& parsed_file, } } if(!result.table_slots[i].joined_to) { - err.add(std::string("query on line ") + std::to_string(def.line) - + std::string(": Could not find item in from cause referenced by ") + err.add(def.line, 96, + std::string("Could not find item in from cause referenced by ") + def.select.from[i].left_of_join + " as the target of a join"); + return result; } } + if(result.table_slots[i].joined_to) { if(def.select.from[i].join_on == "") { result.table_slots[i].joind_by_link = find_common_link(*(result.table_slots[i].joined_to->actual_table), *(result.table_slots[i].actual_table)); if(!result.table_slots[i].joind_by_link) { - err.add(std::string("query on line ") + std::to_string(def.line) - + std::string(": Could not automatically pick a link between ") + err.add(def.line, 97, + std::string("Could not automatically pick a link between ") + result.table_slots[i].joined_to->actual_table->name + " and " + result.table_slots[i].actual_table->name + " to join on"); + return result; } } else { result.table_slots[i].joind_by_link = find_link_by_name(def.select.from[i].join_on, *(result.table_slots[i].joined_to->actual_table), *(result.table_slots[i].actual_table)); if(!result.table_slots[i].joind_by_link) { - err.add(std::string("query on line ") + std::to_string(def.line) - + std::string(": Could not find a link named ") + err.add(def.line, 98, + std::string("Could not find a link named ") + def.select.from[i].join_on + " between " + result.table_slots[i].joined_to->actual_table->name + " and " + result.table_slots[i].actual_table->name); + return result; } } } @@ -1461,15 +1469,17 @@ prepared_query_definition make_prepared_definition(file_def const& parsed_file, if(!found) { if(val.property.type_name != "") { - err.add(std::string("query on line ") + std::to_string(def.line) - + ": From target named " + err.add(def.line, 99, + std::string("From target named ") + val.property.type_name + " could not be found for " + val.property.as_name); + return result; } else { - err.add(std::string("query on line ") + std::to_string(def.line) - + std::string(": From target with property named ") + err.add(def.line, 100, + std::string("From target with property named ") + val.property.member_name + " could not be found for " + val.property.as_name); + return result; } } else { property_def const* referred_property = nullptr; @@ -1486,10 +1496,11 @@ prepared_query_definition make_prepared_definition(file_def const& parsed_file, } } if(!referred_property && !referred_link && val.property.member_name != "id") { - err.add(std::string("query on line ") + std::to_string(def.line) - + std::string(": No property named ") + err.add(def.line, 101, + std::string("No property named ") + val.property.member_name + " could be found in target " + val.property.type_name); + return result; } else { if(!val.is_aggregate) { if(any_is_min_max && after_group_slot) { @@ -1526,6 +1537,9 @@ prepared_query_definition make_prepared_definition(file_def const& parsed_file, while(where_start < where_end) { char const* next_at = advance_to_at(where_start, where_end); result.where_conditional += std::string(where_start, next_at); + if(next_at == where_end) + break; + char const* at_end = advance_to_identifier_end(next_at + 1, where_end); if(at_end < where_end && *at_end == '.') { at_end = advance_to_identifier_end(at_end + 1, where_end); @@ -1555,9 +1569,10 @@ prepared_query_definition make_prepared_definition(file_def const& parsed_file, + std::string(at_end + 1, bracket_end) + ")"; at_end = bracket_end + 1; } else { - err.add(std::string("query on line ") + std::to_string(def.line) - + std::string(": variable of array type missing an indexing expression: ") + err.add(def.line, 102, + std::string("variable of array type missing an indexing expression: ") + std::string(next_at, at_end)); + return result; } } else { @@ -1603,9 +1618,10 @@ prepared_query_definition make_prepared_definition(file_def const& parsed_file, + std::string(at_end + 1, bracket_end) + ")"; at_end = bracket_end + 1; } else { - err.add(std::string("query on line ") + std::to_string(def.line) - + std::string(": variable of array type missing an indexing expression: ") + err.add(def.line, 103, + std::string("variable of array type missing an indexing expression: ") + at_value.name); + return result; } } else { @@ -1620,9 +1636,10 @@ prepared_query_definition make_prepared_definition(file_def const& parsed_file, } if(!found) { - err.add(std::string("query on line ") + std::to_string(def.line) - + std::string(": No replacement found for ") + err.add(def.line, 104, + std::string("No replacement found for ") + std::string(next_at, at_end)); + return result; } where_start = at_end; diff --git a/DataContainerGenerator/parsing.hpp b/DataContainerGenerator/parsing.hpp index 439894f..6dc1817 100644 --- a/DataContainerGenerator/parsing.hpp +++ b/DataContainerGenerator/parsing.hpp @@ -21,13 +21,35 @@ struct parsed_item { char const* terminal; }; +struct row_col_pair { + int32_t row; + int32_t column; +}; + struct error_record { std::string accumulated; + std::string file_name; + + error_record(std::string const& fn) : file_name(fn) {} - void add(std::string const& s) { - if(accumulated.length() > 0) - accumulated += "\n"; + void add(row_col_pair const& rc, int32_t code, std::string const& s) { + //[(position)]: [category] : + + accumulated += file_name; + if(rc.row > 0) { + if(rc.column > 0) { + accumulated += "(" + std::to_string(rc.row) + "," + std::to_string(rc.column) + ")"; + } else { + accumulated += "(" + std::to_string(rc.row) + ")"; + } + } else { + + } + accumulated += ": error "; + accumulated += std::to_string(code); + accumulated += ": "; accumulated += s; + accumulated += "\n"; } }; @@ -36,7 +58,8 @@ char const* advance_to_non_whitespace(char const* pos, char const* end); char const* advance_to_whitespace(char const* pos, char const* end); char const* advance_to_whitespace_or_brace(char const* pos, char const* end); char const* reverse_to_non_whitespace(char const* start, char const* pos); -int32_t calculate_line_from_position(char const* start, char const* pos); + +row_col_pair calculate_line_from_position(char const* start, char const* pos); parsed_item extract_item(char const* input, char const* end, char const* global_start, error_record& err); @@ -268,7 +291,7 @@ struct query_definition { select_statement_definition select; std::vector parameters; std::string name; - int32_t line = 0; + row_col_pair line = row_col_pair{ 0,0 }; }; query_definition parse_query_definition(char const* &start, char const * end, char const * global_start, error_record & err); diff --git a/changes.md b/changes.md index aed2237..a450a30 100644 --- a/changes.md +++ b/changes.md @@ -1,3 +1,10 @@ +### version 0.2.0 + +- added [query](queries.md) interface +- changed the `vector_pool` property interface to work through a proxy object +- improved gcc compatibility of the ve library +- migrated to a more conventional way of reporting errors + ### version 0.1.1 - added `optional` links diff --git a/file_format_documentation.md b/file_format_documentation.md index 4372b27..e37142f 100644 --- a/file_format_documentation.md +++ b/file_format_documentation.md @@ -291,4 +291,4 @@ relationship{ ## Errors -If any errors are detected while parsing an input file, the data container generator will produce a description of those errors as the contents of the output file (instead of the expected valid C++). Error detection in the parser is currently focused on detecting syntactic errors. Logical errors may pass unnoticed, resulting in C++ output that fails to compile. In the long run it would be nice to detect all of the logic errors as well, and if an undetected error has made life difficult for you, please let me know so that detecting it in the future can be given priority. +If any errors are detected while parsing an input file, the data container generator will output a description of those errors to the command line and generate an empty output file and then return -1 (your build system should detect this and understand that the generator has failed). Error detection in the parser is currently focused on detecting syntactic errors. Logical errors may pass unnoticed, resulting in C++ output that fails to compile. In the long run it would be nice to detect all of the logic errors as well, and if an undetected error has made life difficult for you, please let me know so that detecting it in the future can be given priority. diff --git a/objects_and_properties.md b/objects_and_properties.md index 0c05fb9..517ea7b 100644 --- a/objects_and_properties.md +++ b/objects_and_properties.md @@ -119,6 +119,7 @@ All operations on the array of values stored for this property are accessed thro - `range()` returns a `std::pair` containing two pointers, the first to the beginning of the stored array, and the second to the element one past its end (or possibly two null pointers if there is no storage assigned to the array yet) - `at(uint32_t n)` returns the value stored at the nth index of the array (this is a zero-based index) +- `operator[](uint32_t n)` as above - `capacity()` returns the maximum size the array can be grown to before it will have to be internally reallocated within the memory pool - `size()` returns the current size of the array - `contains(type_name)` returns `true` if the value passed compares as equal to one of the values in the array, and `false` otherwise @@ -130,6 +131,8 @@ All operations on the array of values stored for this property are accessed thro - `remove_at(uint32_t n)` remove the item at the nth index from the array (as a zero-based index), by replacing it with what is currently the last value in the array, and then shrinks the size of the array by one. Calling this function with an invalid index into the array will make bad things happen, so don't do it. The proxy object also provides the standard `begin()` and `end()` functions so that it can be used in a range-based for loop. Finally, the functions that modify the contents of the array of values will not be available if the property is access through a constant reference or pointer to the data container. + +NOTE: the proxy objects should not be stored in general. They certainly should not be stored over any operation that would create or delete an object instance. You should also never access the same underlying `vector_pool` property through two different proxy objects; don't reuse an old proxy object after you have obtained a new one for that same property via `get`. #### `array` diff --git a/queries.md b/queries.md index 98a6785..1b5270a 100644 --- a/queries.md +++ b/queries.md @@ -125,10 +125,10 @@ Note that, for performance reasons, there are some complications when the link b By default, every item in a from clause is joined to the preceding item. However, that doesn't have to be the case. You can also write a join as `𝘳𝘦𝘧𝘦𝘳𝘦𝘯𝘤𝘦 𝘯𝘢𝘮𝘦.join`. In this case the item following the join will be joined to the item named by 𝘳𝘦𝘧𝘦𝘳𝘦𝘯𝘤𝘦 𝘯𝘢𝘮𝘦, assuming that it has been defined at some point prior in the from statement. -For example, you could iterate over pair of siblings of a person with a query such as +For example, you could iterate over pairs of children of a person with a query such as ``` -base.id, sibling_a.id, sibling_b.id +sibling_a.id, sibling_b.id from @person_param as base, join on parent parentage, join on child person as sibling_a, base.join on parent parentage, join on child person as sibling_b