From 0dc33a4dd49eb560e98b24090969fd618a4c6198 Mon Sep 17 00:00:00 2001 From: Aldrik Ramaekers Date: Sat, 18 Oct 2025 08:58:32 +0200 Subject: refactor memops --- TODO | 2 +- include/memops.hpp | 1 + manual/02_countries.md | 6 +++++- src/administration.cpp | 14 +++++++------- src/administration_reader.cpp | 2 +- src/administration_writer.cpp | 8 ++++---- src/ai_providers/DeepSeek.cpp | 4 ++-- src/ai_providers/openAI.cpp | 4 ++-- src/countries.cpp | 2 +- src/importer.cpp | 4 ++-- src/memops.cpp | 5 +++++ src/ui/ui_contacts.cpp | 9 +++++---- src/ui/ui_log.cpp | 2 -- src/ui/ui_projects.cpp | 2 -- src/ui/ui_settings.cpp | 10 +++++----- tests/nl_tax_tests.cpp | 6 +++--- 16 files changed, 44 insertions(+), 37 deletions(-) diff --git a/TODO b/TODO index fbfa583..9b69dbe 100644 --- a/TODO +++ b/TODO @@ -3,9 +3,9 @@ TODO: Refactor: - Can we get rid of taxrate id in invoice? this would avoid reference conflicts. - refactor _add functions to use _import functions -- replace memset with memops function - replace strncpy and similar with strops functions - There is alot of memory leakage +- remove country list from config and use country namespace iteration. Testing: - write tests for all NL tax categories diff --git a/include/memops.hpp b/include/memops.hpp index a3d9fbd..9901d0c 100644 --- a/include/memops.hpp +++ b/include/memops.hpp @@ -24,5 +24,6 @@ namespace memops { void* stack_alloc(size_t size); void unalloc(void *ptr); void* copy(void* destination, const void* source, size_t num); + void zero(void* destination, size_t num); } \ No newline at end of file diff --git a/manual/02_countries.md b/manual/02_countries.md index 6fcd8bf..33ccb8f 100644 --- a/manual/02_countries.md +++ b/manual/02_countries.md @@ -1,4 +1,8 @@ # Supported countries This section lists all supported countries. If the country you operate from is not listed below, some reporting requirements might not be handled by OpenBooks. -**The netherlands**: Quarterly tax reports. \ No newline at end of file +**Invoicing**: +The Netherlands + +**Tax reporting**: +The Netherlands (for invoices after 1 January 2020) \ No newline at end of file diff --git a/src/administration.cpp b/src/administration.cpp index a6f7187..f79a0af 100644 --- a/src/administration.cpp +++ b/src/administration.cpp @@ -303,7 +303,7 @@ void administration_create() list_init(&g_administration.cost_centers); strops::copy(g_administration.path, "", sizeof(g_administration.path)); - memset(&g_administration.ai_service, 0, sizeof(ai_service)); + memops::zero(&g_administration.ai_service, sizeof(ai_service)); logger::info("Setup took %.3fms.", STOPWATCH_TIME); } @@ -1016,7 +1016,7 @@ a_err administration::contact_is_valid(contact data) contact administration::contact_create_empty() { contact result; - memset(&result, 0, sizeof(contact)); + memops::zero(&result, sizeof(contact)); strops::format(result.id, sizeof(result.id), "C/%d", create_id()); return result; } @@ -1196,7 +1196,7 @@ a_err administration::project_remove(project data) project administration::project_create_empty() { project result; - memset(&result, 0, sizeof(project)); + memops::zero(&result, sizeof(project)); result.state = project_state::PROJECT_RUNNING; result.start_date = time(NULL); result.start_date -= (result.start_date % 86400); @@ -1211,7 +1211,7 @@ project administration::project_create_empty() tax_rate administration::tax_rate_create_empty() { tax_rate result; - memset(&result, 0, sizeof(tax_rate)); + memops::zero(&result, sizeof(tax_rate)); strops::format(result.id, sizeof(result.id), "T/%d", create_id()); strops::format(result.category_code, sizeof(result.category_code), "S"); // S = standard rate. return result; @@ -1380,7 +1380,7 @@ u32 administration::cost_center_count() cost_center administration::cost_center_create_empty() { cost_center cc; - memset(&cc, 0, sizeof(cost_center)); + memops::zero(&cc, sizeof(cost_center)); strops::format(cc.id, sizeof(cc.id), "E/%d", create_id()); return cc; } @@ -1571,7 +1571,7 @@ bool administration::invoice_has_intra_community_services(invoice* invoice) invoice administration::invoice_create_empty() { invoice result; - memset(&result, 0, sizeof(invoice)); + memops::zero(&result, sizeof(invoice)); strops::format(result.id, sizeof(result.id), "I/%d", create_id()); strops::format(result.sequential_number, sizeof(result.id), "INV%010d", create_sequence_number()); result.issued_at = time(NULL); @@ -2101,7 +2101,7 @@ a_err administration::billing_item_add_to_invoice(invoice* invoice, billing_item billing_item administration::billing_item_create_empty() { billing_item item; - memset(&item, 0, sizeof(billing_item)); + memops::zero(&item, sizeof(billing_item)); item.amount = 1; return item; } \ No newline at end of file diff --git a/src/administration_reader.cpp b/src/administration_reader.cpp index c22638b..41ebdca 100644 --- a/src/administration_reader.cpp +++ b/src/administration_reader.cpp @@ -78,7 +78,7 @@ bool administration_reader::open_existing(char* file_path) unsigned long long size = zip_entry_size(zip); char* buffer = (char*)memops::alloc(size+1); - memset(buffer, 0, size+1); + memops::zero(buffer, size+1); zip_entry_read(zip, (void**)&buffer, (size_t*)&size); if (strlen(name) == 0) continue; diff --git a/src/administration_writer.cpp b/src/administration_writer.cpp index 5010dd8..6b28367 100644 --- a/src/administration_writer.cpp +++ b/src/administration_writer.cpp @@ -93,7 +93,7 @@ static char* copy_template(const char* template_str, int* buf_size) size_t template_size = strlen(template_str); size_t buf_length = template_size*5; // Ballpark file content size. char* file_content = (char*)memops::alloc(buf_length); - memset(file_content, 0, buf_length); + memops::zero(file_content, buf_length); memops::copy(file_content, template_str, template_size); *buf_size = (int)buf_length; return file_content; @@ -334,7 +334,7 @@ bool administration_writer::save_invoice_blocking(invoice inv) bool result = 1; int buf_length = 150000; // Ballpark file content size. char* file_content = (char*)memops::alloc(buf_length); - memset(file_content, 0, buf_length); + memops::zero(file_content, buf_length); memops::copy(file_content, file_template::peppol_invoice_template, strlen(file_template::peppol_invoice_template)); struct tm *tm_info = 0; @@ -412,7 +412,7 @@ bool administration_writer::save_invoice_blocking(invoice inv) u32 tax_subtotal_list_buffer_size = (u32)strlen(file_template::peppol_invoice_tax_subtotal_template) * 2 * tax_rate_count; // Ballpark list size. char* tax_subtotal_list_buffer = (char*)memops::alloc(tax_subtotal_list_buffer_size); - memset(tax_subtotal_list_buffer, 0, tax_subtotal_list_buffer_size); + memops::zero(tax_subtotal_list_buffer, tax_subtotal_list_buffer_size); u32 tax_subtotal_list_buffer_cursor = 0; for (u32 i = 0; i < tax_rate_count; i++) @@ -460,7 +460,7 @@ bool administration_writer::save_invoice_blocking(invoice inv) u32 billing_item_list_buffer_size = (u32)strlen(file_template::peppol_invoice_line_template) * 2 * billing_item_count; // Ballpark list size. char* billing_item_list_buffer = (char*)memops::alloc(billing_item_list_buffer_size); - memset(billing_item_list_buffer, 0, billing_item_list_buffer_size); + memops::zero(billing_item_list_buffer, billing_item_list_buffer_size); u32 billing_item_list_buffer_cursor = 0; for (u32 i = 0; i < billing_item_count; i++) diff --git a/src/ai_providers/DeepSeek.cpp b/src/ai_providers/DeepSeek.cpp index 2bc4dde..0a7dbbd 100644 --- a/src/ai_providers/DeepSeek.cpp +++ b/src/ai_providers/DeepSeek.cpp @@ -64,7 +64,7 @@ static bool _DeepSeek_query_with_file(char* query, size_t query_length, char* fi char* response_body = (char*)res->body.c_str(); *response = (char*)memops::alloc(100000); - memset(*response, 0, 100000); + memops::zero(*response, 100000); strncpy(*response, response_body, 100000); strops::get_json_value(*response, "content", *response, 100000); @@ -91,7 +91,7 @@ static bool _DeepSeek_upload_file(char* file_path, char* file_id, size_t file_id size_t buffer_size = sz + QUERY_BUFFER_SIZE; char* file_content_buffer = (char*)memops::alloc(buffer_size); - memset(file_content_buffer, 0, buffer_size); + memops::zero(file_content_buffer, buffer_size); query_buffer = file_content_buffer; diff --git a/src/ai_providers/openAI.cpp b/src/ai_providers/openAI.cpp index fba050c..0afd2e7 100644 --- a/src/ai_providers/openAI.cpp +++ b/src/ai_providers/openAI.cpp @@ -52,14 +52,14 @@ static bool _openAI_query_with_file(char* query, size_t query_length, char* file char* response_body = (char*)res->body.c_str(); *response = (char*)memops::alloc(100000); - memset(*response, 0, 100000); + memops::zero(*response, 100000); strncpy(*response, response_body, 100000); strops::get_json_value(*response, "text", *response, 100000); *response = strops::unprep_str_from_json(*response); #else *response = (char*)memops::alloc(100000); - memset(*response, 0, 100000); + memops::zero(*response, 100000); strops::copy(*response, " urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0 urn:fdc:peppol.eu:2017:poacc:billing:01:1.0 492043632 2024-09-01 2024-09-01 380 USD Final invoice do:team:67840ecb-44e2-472e-bc45-801bd4e1f1fe DigitalOcean LLC 101 Avenue of the Americas 2nd Floor New York 10013 NY US EU528002224 VAT DigitalOcean LLC My Team Keerderstraat 81 Maastricht 6226 XW LI NL VAT aldrikboy@gmail.com 492043632 3.49 15.60 3.28 VAT 1.00 0.21 VAT 16.60 16.60 20.09 20.09 1 16.60 false Discount Product Usage Charges Internal Tax Rate ID VAT ", 100000); #endif diff --git a/src/countries.cpp b/src/countries.cpp index 5712a7f..7170e5b 100644 --- a/src/countries.cpp +++ b/src/countries.cpp @@ -21,7 +21,7 @@ static country_impl country_map[] = { _nl_country_impl, - // Add new locales here. + // Add new countries here. }; static const u32 country_map_count = sizeof(country_map) / sizeof(country_map[0]); diff --git a/src/importer.cpp b/src/importer.cpp index e40de5b..ae8bada 100644 --- a/src/importer.cpp +++ b/src/importer.cpp @@ -59,7 +59,7 @@ static int _ai_document_to_invoice_t(void *arg) { size_t query_buffer_len = 50000; char* template_buffer = (char*)memops::alloc(query_buffer_len); - memset(template_buffer, 0, query_buffer_len); + memops::zero(template_buffer, query_buffer_len); strncpy(template_buffer, file_template::peppol_invoice_template, query_buffer_len); strops::replace(template_buffer, 50000, "{{INVOICE_LINE_LIST}}", file_template::peppol_invoice_line_template); @@ -192,7 +192,7 @@ importer::model_list_request* importer::ai_get_available_models(ai_provider serv result->status = importer::status::IMPORT_STARTING; result->result_count = 0; result->service = service; - memset(result->result, 0, sizeof(result->result)); + memops::zero(result->result, sizeof(result->result)); thrd_t thr; if (thrd_create(&thr, _ai_get_available_models_t, result) != thrd_success) { diff --git a/src/memops.cpp b/src/memops.cpp index 09e592e..a05644a 100644 --- a/src/memops.cpp +++ b/src/memops.cpp @@ -38,3 +38,8 @@ void* memops::copy(void* destination, const void* source, size_t num) { return memcpy(destination, source, num); } + +void memops::zero(void* destination, size_t num) +{ + memset(destination, 0, num); +} \ No newline at end of file diff --git a/src/ui/ui_contacts.cpp b/src/ui/ui_contacts.cpp index cc5a7e0..ff1f424 100644 --- a/src/ui/ui_contacts.cpp +++ b/src/ui/ui_contacts.cpp @@ -14,13 +14,14 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include "strops.hpp" -#include "config.hpp" #include "ui.hpp" #include "imgui.h" +#include "strops.hpp" +#include "config.hpp" +#include "memops.hpp" +#include "locales.hpp" #include "administration.hpp" #include "administration_writer.hpp" -#include "locales.hpp" static ui::view_state current_view_state = ui::view_state::LIST_ALL; static contact selected_for_removal; @@ -42,7 +43,7 @@ void ui::setup_contacts() { current_view_state = ui::view_state::LIST_ALL; active_contact = active_contact = administration::contact_create_empty(); - memset(&selected_for_removal, 0, sizeof(contact)); + memops::zero(&selected_for_removal, sizeof(contact)); } void draw_addressee_form_ex(delivery_info* buffer, bool viewing_only = false) diff --git a/src/ui/ui_log.cpp b/src/ui/ui_log.cpp index d19e26e..1f4aa84 100644 --- a/src/ui/ui_log.cpp +++ b/src/ui/ui_log.cpp @@ -14,8 +14,6 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include - #include "ui.hpp" #include "imgui.h" #include "logger.hpp" diff --git a/src/ui/ui_projects.cpp b/src/ui/ui_projects.cpp index 43a8eb4..5e0df0c 100644 --- a/src/ui/ui_projects.cpp +++ b/src/ui/ui_projects.cpp @@ -14,8 +14,6 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include - #include "ui.hpp" #include "imgui.h" #include "administration.hpp" diff --git a/src/ui/ui_settings.cpp b/src/ui/ui_settings.cpp index a4b5748..7de543f 100644 --- a/src/ui/ui_settings.cpp +++ b/src/ui/ui_settings.cpp @@ -158,7 +158,7 @@ static void draw_vat_rates() if (ImGui::Button(locale::get("form.cancel"))) { is_editing_item = false; is_adding_item = false; - memset(&new_tax_rate, 0, sizeof(new_tax_rate)); + memops::zero(&new_tax_rate, sizeof(new_tax_rate)); } } else @@ -204,7 +204,7 @@ static void draw_vat_rates() if (ImGui::Button(locale::get("form.cancel"))) { is_editing_item = false; is_adding_item = false; - memset(&new_tax_rate, 0, sizeof(new_tax_rate)); + memops::zero(&new_tax_rate, sizeof(new_tax_rate)); } } } @@ -252,7 +252,7 @@ static void draw_cost_centers() administration::cost_center_update(new_cost_center); - memset(&new_cost_center, 0, sizeof(new_cost_center)); + memops::zero(&new_cost_center, sizeof(new_cost_center)); ui::destroy_settings(); ui::setup_settings(); @@ -263,7 +263,7 @@ static void draw_cost_centers() if (ImGui::Button(locale::get("form.cancel"))) { is_editing_item = false; is_adding_item = false; - memset(&new_cost_center, 0, sizeof(new_cost_center)); + memops::zero(&new_cost_center, sizeof(new_cost_center)); } } else @@ -316,7 +316,7 @@ static void draw_cost_centers() if (ImGui::Button(locale::get("form.cancel"))) { is_adding_item = false; is_editing_item = false; - memset(&new_cost_center, 0, sizeof(new_cost_center)); + memops::zero(&new_cost_center, sizeof(new_cost_center)); } } diff --git a/tests/nl_tax_tests.cpp b/tests/nl_tax_tests.cpp index 31382ed..20d70c8 100644 --- a/tests/nl_tax_tests.cpp +++ b/tests/nl_tax_tests.cpp @@ -50,7 +50,7 @@ TEST _nl_tax_1b(void) PASS(); } -TEST _nl_tax_1d(void) +TEST _nl_tax_1c(void) { administration::create_default(test_file_path); administration::company_info_set(_create_nl_business()); @@ -71,7 +71,7 @@ TEST _nl_tax_1d(void) administration::create_tax_statement(&statement); ASSERT_EQ(statement.report_count, 1); - tax_line* tl = administration::get_tax_line_from_report(&statement.reports[0], "1d"); + tax_line* tl = administration::get_tax_line_from_report(&statement.reports[0], "1c"); ASSERT_EQ(tl->total_net, 45.0f); ASSERT_EQ(tl->total_tax, 45.0f * 0.05f); @@ -143,7 +143,7 @@ TEST _nl_tax_2currency(void) SUITE(nl_tax_statement) { RUN_TEST(_nl_tax_1a); RUN_TEST(_nl_tax_1b); - RUN_TEST(_nl_tax_1d); + RUN_TEST(_nl_tax_1c); RUN_TEST(_nl_tax_1e); RUN_TEST(_nl_tax_2currency); } \ No newline at end of file -- cgit v1.2.3-70-g09d2