summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAldrik Ramaekers <aldrikboy@gmail.com>2025-10-05 15:41:23 +0200
committerAldrik Ramaekers <aldrikboy@gmail.com>2025-10-05 15:41:23 +0200
commit8aa66a6c6c0d8984b7d2668c03bad5a3b29e3a33 (patch)
treed7d985151b5bcd6687aead3547bdfbdb0600a8c6
parentb278d242d03ba614779243ec9e9495fc95abea3d (diff)
memops wrapper, remove unused includes
-rw-r--r--include/memops.hpp28
-rw-r--r--libs/xml.c/src/xml.c2
-rw-r--r--run.bat2
-rw-r--r--src/administration.cpp119
-rw-r--r--src/administration_reader.cpp10
-rw-r--r--src/administration_writer.cpp68
-rw-r--r--src/ai_providers/DeepSeek.cpp17
-rw-r--r--src/ai_providers/openAI.cpp23
-rw-r--r--src/importer.cpp20
-rw-r--r--src/logger.cpp4
-rw-r--r--src/memops.cpp40
-rw-r--r--src/strops.cpp8
-rw-r--r--src/ui/imgui_extensions.cpp21
-rw-r--r--src/ui/ui_earnings.cpp8
-rw-r--r--src/ui/ui_expenses.cpp17
-rw-r--r--src/ui/ui_invoices.cpp15
-rw-r--r--src/ui/ui_settings.cpp14
-rw-r--r--tests/test_helper.cpp18
18 files changed, 235 insertions, 199 deletions
diff --git a/include/memops.hpp b/include/memops.hpp
new file mode 100644
index 0000000..a3d9fbd
--- /dev/null
+++ b/include/memops.hpp
@@ -0,0 +1,28 @@
+/*
+* Copyright (c) 2025 Aldrik Ramaekers <aldrik.ramaekers@gmail.com>
+*
+* Permission to use, copy, modify, and/or distribute this software for any
+* purpose with or without fee is hereby granted, provided that the above
+* copyright notice and this permission notice appear in all copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+#pragma once
+
+#include "config.hpp"
+
+namespace memops {
+
+ void* alloc(size_t size);
+ void* stack_alloc(size_t size);
+ void unalloc(void *ptr);
+ void* copy(void* destination, const void* source, size_t num);
+
+} \ No newline at end of file
diff --git a/libs/xml.c/src/xml.c b/libs/xml.c/src/xml.c
index ffebdb5..0a93e57 100644
--- a/libs/xml.c/src/xml.c
+++ b/libs/xml.c/src/xml.c
@@ -20,7 +20,7 @@
*
* 3. This notice may not be removed or altered from any source distribution.
*/
-#define _CRT_SECURE_NO_WARNINGS
+//#define _CRT_SECURE_NO_WARNINGS
#include "xml.h"
#ifdef XML_PARSER_VERBOSE
diff --git a/run.bat b/run.bat
index 46c394b..a6f535c 100644
--- a/run.bat
+++ b/run.bat
@@ -32,7 +32,7 @@ set LIB_SOURCES=libs\imgui-1.92.1\backends\imgui_impl_dx11.cpp^
@set LIBS=opengl32.lib Advapi32.lib Shell32.lib Ole32.lib User32.lib Pathcch.lib D3D11.lib Comdlg32.lib Kernel32.lib /LIBPATH:"libs/openssl-3.6.0-beta1/x64/lib" libssl.lib libcrypto.lib
@set FLAGS=/nologo /Ob0 /MD /Oy- /Zi /FS /W4 /EHsc /utf-8 /F4000000
@set INCLUDE_DIRS=/I"libs/imgui-1.92.1" /I"libs/imgui-1.92.1/backends" /I"/" /I"libs/openssl-3.6.0-beta1/x64/include" /I"libs/cpp-httplib" /I"libs/timer_lib" /I"libs/greatest" /I"libs/simclist-1.5" /I"libs/tinyfiledialogs" /I"libs/zip/src" /I"libs/xml.c/src" /I"libs/" /Iinclude
-@set DEFINITIONS=/D_BUILD_DATE_=\"%date%\" /D_COMMIT_=\"%COMMIT_ID%\" /D_PLATFORM_=\"win64\"
+@set DEFINITIONS=/D_BUILD_DATE_=\"%date%\" /D_COMMIT_=\"%COMMIT_ID%\" /D_PLATFORM_=\"win64\" /D_CRT_SECURE_NO_WARNINGS
if "%1"=="-t" @set SOURCES= tests\main.cpp src\administration.cpp src\administration_writer.cpp src\administration_reader.cpp src\strops.cpp src\logger.cpp src\locales.cpp src\locales\*.cpp src\ai_providers\*.cpp src\ui\helpers.cpp
if "%1"=="-t" @set OUT_EXE=accounting_tests
diff --git a/src/administration.cpp b/src/administration.cpp
index a3d3c2f..9790281 100644
--- a/src/administration.cpp
+++ b/src/administration.cpp
@@ -14,13 +14,10 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#define _CRT_SECURE_NO_WARNINGS
-
-#include <stdlib.h>
#include <assert.h>
#include <time.h>
-#include <stdio.h>
+#include "memops.hpp"
#include "logger.hpp"
#include "strops.hpp"
#include "administration.hpp"
@@ -59,11 +56,11 @@ static void create_default_tax_rates()
{
#define ADD_BRACKET(_country, _rate, _code)\
{\
- tax_rate* tb = (tax_rate*)malloc(sizeof(tax_rate));\
+ tax_rate* tb = (tax_rate*)memops::alloc(sizeof(tax_rate));\
strops::format(tb->id, sizeof(tb->id), "T/%d", create_id());\
- memcpy(tb->country_code, _country, sizeof(tb->country_code));\
+ memops::copy(tb->country_code, _country, sizeof(tb->country_code));\
tb->rate = _rate;\
- memcpy(tb->category_code, _code, sizeof(tb->category_code));\
+ memops::copy(tb->category_code, _code, sizeof(tb->category_code));\
list_append(&g_administration.tax_rates, tb);\
g_administration.next_id++;\
if (taxrate_changed_event_callback) taxrate_changed_event_callback(tb);\
@@ -222,10 +219,10 @@ static void create_default_cost_centers()
{
#define ADD_COSTCENTER(_description, _code)\
{\
- cost_center* tb = (cost_center*)malloc(sizeof(cost_center));\
+ cost_center* tb = (cost_center*)memops::alloc(sizeof(cost_center));\
strops::format(tb->id, sizeof(tb->id), "E/%d", create_id());\
- memcpy(tb->description, _description, sizeof(tb->description));\
- memcpy(tb->code, _code, sizeof(tb->code));\
+ memops::copy(tb->description, _description, sizeof(tb->description));\
+ memops::copy(tb->code, _code, sizeof(tb->code));\
list_append(&g_administration.cost_centers, tb);\
g_administration.next_id++;\
if (costcenter_changed_event_callback) costcenter_changed_event_callback(tb);\
@@ -314,7 +311,7 @@ static void administration_destroy_list(list_t *list)
list_iterator_start(list);
while (list_iterator_hasnext(list)) {
void* c = (void *)list_iterator_next(list);
- free(c);
+ memops::unalloc(c);
}
list_iterator_stop(list);
list_destroy(list);
@@ -487,7 +484,7 @@ void administration::create_income_statement(income_statement* statement)
u32 invoice_count = administration::invoice_count();
if (invoice_count == 0) return;
- invoice* invoice_buffer = (invoice*)malloc(sizeof(invoice)*invoice_count);
+ invoice* invoice_buffer = (invoice*)memops::alloc(sizeof(invoice)*invoice_count);
invoice_count = administration::invoice_get_all(invoice_buffer);
// Find oldest and youngest invoice.
@@ -531,12 +528,12 @@ void administration::create_income_statement(income_statement* statement)
strops::format(quarter.quarter_str, MAX_LEN_SHORT_DESC, "%dQ%d", quarter.quarter+1, quarter.year);
project_count = administration::project_count();
- project* project_buffer = (project*)malloc(sizeof(project)*project_count);
+ project* project_buffer = (project*)memops::alloc(sizeof(project)*project_count);
project_count = administration::project_get_all(project_buffer);
assert(project_count <= MAX_LEN_QUARTERLY_REPORT_PROJECTS);
costcenter_count = administration::cost_center_count();
- cost_center* costcenter_buffer = (cost_center*)malloc(sizeof(cost_center)*costcenter_count);
+ cost_center* costcenter_buffer = (cost_center*)memops::alloc(sizeof(cost_center)*costcenter_count);
costcenter_count = administration::cost_center_get_all(costcenter_buffer);
assert(costcenter_count <= MAX_LEN_PROJECT_REPORT_COSTCENTERS);
@@ -565,8 +562,8 @@ void administration::create_income_statement(income_statement* statement)
statement->quarters[statement->quarter_count++] = quarter;
- free(costcenter_buffer);
- free(project_buffer);
+ memops::unalloc(costcenter_buffer);
+ memops::unalloc(project_buffer);
}
// Fill quarters.
@@ -665,7 +662,7 @@ void administration::create_income_statement(income_statement* statement)
//administration_debug_print_income_statement(statement);
- free(invoice_buffer);
+ memops::unalloc(invoice_buffer);
logger::info("Created income statement in %.3fms.", STOPWATCH_TIME);
}
@@ -714,10 +711,10 @@ a_err administration::contact_import(contact data)
return A_ERR_SUCCESS;
}
- contact* new_contact = (contact*)malloc(sizeof(contact));
+ contact* new_contact = (contact*)memops::alloc(sizeof(contact));
if (!new_contact) return A_ERR_GENERIC;
- memcpy((void*)new_contact, (void*)&data, sizeof(contact));
+ memops::copy((void*)new_contact, (void*)&data, sizeof(contact));
if (!list_append(&g_administration.contacts, new_contact)) {
return A_ERR_GENERIC;
}
@@ -730,10 +727,10 @@ a_err administration::contact_add(contact data)
a_err result = administration::contact_is_valid(data);
if (result != A_ERR_SUCCESS) return result;
- contact* new_contact = (contact*)malloc(sizeof(contact));
+ contact* new_contact = (contact*)memops::alloc(sizeof(contact));
if (!new_contact) return A_ERR_GENERIC;
- memcpy((void*)new_contact, (void*)&data, sizeof(contact));
+ memops::copy((void*)new_contact, (void*)&data, sizeof(contact));
if (!list_append(&g_administration.contacts, new_contact)) {
return A_ERR_GENERIC;
}
@@ -756,7 +753,7 @@ a_err administration::contact_update(contact data)
contact* c = (contact *)list_iterator_next(&g_administration.contacts);
if (strcmp(c->id, data.id) == 0) {
- memcpy(c, &data, sizeof(data));
+ memops::copy(c, &data, sizeof(data));
if (contact_changed_event_callback) contact_changed_event_callback(c);
if (data_changed_event_callback) data_changed_event_callback();
@@ -782,7 +779,7 @@ a_err administration::contact_remove(contact data)
if (data_deleted_event_callback) data_deleted_event_callback(c->id);
- free(c);
+ memops::unalloc(c);
return A_ERR_SUCCESS;
}
}
@@ -1013,10 +1010,10 @@ a_err administration::project_import(project data)
a_err result = administration::project_is_valid(data);
if (result != A_ERR_SUCCESS) return result;
- project* new_project = (project*)malloc(sizeof(project));
+ project* new_project = (project*)memops::alloc(sizeof(project));
if (!new_project) return A_ERR_GENERIC;
- memcpy((void*)new_project, (void*)&data, sizeof(project));
+ memops::copy((void*)new_project, (void*)&data, sizeof(project));
if (!list_append(&g_administration.projects, new_project)) {
return A_ERR_GENERIC;
}
@@ -1029,10 +1026,10 @@ a_err administration::project_add(project data)
a_err result = administration::project_is_valid(data);
if (result != A_ERR_SUCCESS) return result;
- project* new_project = (project*)malloc(sizeof(project));
+ project* new_project = (project*)memops::alloc(sizeof(project));
if (!new_project) return A_ERR_GENERIC;
- memcpy((void*)new_project, (void*)&data, sizeof(project));
+ memops::copy((void*)new_project, (void*)&data, sizeof(project));
if (!list_append(&g_administration.projects, new_project)) {
return A_ERR_GENERIC;
@@ -1056,7 +1053,7 @@ a_err administration::project_update(project data)
project* c = (project *)list_iterator_next(&g_administration.projects);
if (strcmp(c->id, data.id) == 0) {
- memcpy(c, &data, sizeof(data));
+ memops::copy(c, &data, sizeof(data));
list_iterator_stop(&g_administration.projects);
if (project_changed_event_callback) project_changed_event_callback(c);
@@ -1082,7 +1079,7 @@ a_err administration::project_remove(project data)
if (data_deleted_event_callback) data_deleted_event_callback(c->id);
- free(c);
+ memops::unalloc(c);
return A_ERR_SUCCESS;
}
}
@@ -1163,10 +1160,10 @@ u32 administration::tax_rate_count()
a_err administration::tax_rate_import(tax_rate data)
{
- tax_rate* tb = (tax_rate*)malloc(sizeof(tax_rate));
+ tax_rate* tb = (tax_rate*)memops::alloc(sizeof(tax_rate));
if (!tb) return A_ERR_GENERIC;
- memcpy((void*)tb, (void*)&data, sizeof(tax_rate));
+ memops::copy((void*)tb, (void*)&data, sizeof(tax_rate));
if (!list_append(&g_administration.tax_rates, tb)) {
return A_ERR_GENERIC;
}
@@ -1178,10 +1175,10 @@ a_err administration::tax_rate_import(tax_rate data)
a_err administration::tax_rate_add(tax_rate data)
{
- tax_rate* tb = (tax_rate*)malloc(sizeof(tax_rate));
+ tax_rate* tb = (tax_rate*)memops::alloc(sizeof(tax_rate));
if (!tb) return A_ERR_GENERIC;
- memcpy((void*)tb, (void*)&data, sizeof(tax_rate));
+ memops::copy((void*)tb, (void*)&data, sizeof(tax_rate));
if (!list_append(&g_administration.tax_rates, tb)) {
return A_ERR_GENERIC;
}
@@ -1247,7 +1244,7 @@ a_err administration::tax_rate_update(tax_rate data)
tax_rate* c = (tax_rate *)list_iterator_next(&g_administration.tax_rates);
if (strcmp(c->id, data.id) == 0) {
- memcpy(c, &data, sizeof(data));
+ memops::copy(c, &data, sizeof(data));
list_iterator_stop(&g_administration.tax_rates);
if (taxrate_changed_event_callback) taxrate_changed_event_callback(c);
@@ -1345,10 +1342,10 @@ a_err administration::cost_center_import(cost_center data)
a_err result = administration::cost_center_is_valid(data);
if (result != A_ERR_SUCCESS) return result;
- cost_center* tb = (cost_center*)malloc(sizeof(cost_center));
+ cost_center* tb = (cost_center*)memops::alloc(sizeof(cost_center));
if (!tb) return A_ERR_GENERIC;
- memcpy(tb, &data, sizeof(cost_center));
+ memops::copy(tb, &data, sizeof(cost_center));
if (!list_append(&g_administration.cost_centers, tb)) {
return A_ERR_GENERIC;
}
@@ -1360,10 +1357,10 @@ a_err administration::cost_center_add(cost_center data)
a_err result = administration::cost_center_is_valid(data);
if (result != A_ERR_SUCCESS) return result;
- cost_center* tb = (cost_center*)malloc(sizeof(cost_center));
+ cost_center* tb = (cost_center*)memops::alloc(sizeof(cost_center));
if (!tb) return A_ERR_GENERIC;
- memcpy((void*)tb, (void*)&data, sizeof(cost_center));
+ memops::copy((void*)tb, (void*)&data, sizeof(cost_center));
if (!list_append(&g_administration.cost_centers, tb)) {
return A_ERR_GENERIC;
}
@@ -1386,7 +1383,7 @@ a_err administration::cost_center_update(cost_center data)
cost_center* c = (cost_center *)list_iterator_next(&g_administration.cost_centers);
if (strcmp(c->id, data.id) == 0) {
- memcpy(c, &data, sizeof(data));
+ memops::copy(c, &data, sizeof(data));
list_iterator_stop(&g_administration.cost_centers);
if (costcenter_changed_event_callback) costcenter_changed_event_callback(c);
@@ -1532,7 +1529,7 @@ a_err administration::invoice_remove(invoice* inv)
if (inv->is_outgoing) g_administration.invoice_count--;
else g_administration.expense_count--;
- free(c);
+ memops::unalloc(c);
return A_ERR_SUCCESS;
}
}
@@ -1542,13 +1539,13 @@ a_err administration::invoice_remove(invoice* inv)
static void invoice_set_addressee(invoice* inv, contact contact)
{
- memcpy(&inv->addressee.name, &contact.name, sizeof(inv->addressee.name));
- memcpy(&inv->addressee.address.address1, &contact.address.address1, sizeof(inv->addressee.address.address1));
- memcpy(&inv->addressee.address.address2, &contact.address.address2, sizeof(inv->addressee.address.address2));
- memcpy(&inv->addressee.address.city, &contact.address.city, sizeof(inv->addressee.address.city));
- memcpy(&inv->addressee.address.postal, &contact.address.postal, sizeof(inv->addressee.address.postal));
- memcpy(&inv->addressee.address.region, &contact.address.region, sizeof(inv->addressee.address.region));
- memcpy(&inv->addressee.address.country_code, &contact.address.country_code, sizeof(inv->addressee.address.country_code));
+ memops::copy(&inv->addressee.name, &contact.name, sizeof(inv->addressee.name));
+ memops::copy(&inv->addressee.address.address1, &contact.address.address1, sizeof(inv->addressee.address.address1));
+ memops::copy(&inv->addressee.address.address2, &contact.address.address2, sizeof(inv->addressee.address.address2));
+ memops::copy(&inv->addressee.address.city, &contact.address.city, sizeof(inv->addressee.address.city));
+ memops::copy(&inv->addressee.address.postal, &contact.address.postal, sizeof(inv->addressee.address.postal));
+ memops::copy(&inv->addressee.address.region, &contact.address.region, sizeof(inv->addressee.address.region));
+ memops::copy(&inv->addressee.address.country_code, &contact.address.country_code, sizeof(inv->addressee.address.country_code));
}
a_err administration::invoice_update(invoice* inv)
@@ -1565,7 +1562,7 @@ a_err administration::invoice_update(invoice* inv)
if (strcmp(c->id, inv->id) == 0)
{
- memcpy(c, inv, sizeof(invoice));
+ memops::copy(c, inv, sizeof(invoice));
list_iterator_stop(&g_administration.invoices);
if (invoice_changed_event_callback) invoice_changed_event_callback(c);
@@ -1591,10 +1588,10 @@ a_err administration::invoice_import(invoice* inv)
inv->is_outgoing = strcmp(inv->supplier.id, MY_COMPANY_ID) == 0;
invoice copy = administration::invoice_create_copy(inv); // Create copy to make copy of billing item list.
- invoice* new_inv = (invoice*)malloc(sizeof(invoice));
+ invoice* new_inv = (invoice*)memops::alloc(sizeof(invoice));
if (!new_inv) return A_ERR_GENERIC;
- memcpy(new_inv, &copy, sizeof(invoice));
+ memops::copy(new_inv, &copy, sizeof(invoice));
if (!list_append(&g_administration.invoices, new_inv)) {
return A_ERR_GENERIC;
@@ -1622,10 +1619,10 @@ a_err administration::invoice_add(invoice* inv)
strops::copy(inv->payment_means.payer_bank_account, inv->customer.bank_account, sizeof(inv->payment_means.payer_bank_account));
invoice copy = administration::invoice_create_copy(inv); // Create copy to make copy of billing item list.
- invoice* new_inv = (invoice*)malloc(sizeof(invoice));
+ invoice* new_inv = (invoice*)memops::alloc(sizeof(invoice));
if (!new_inv) return A_ERR_GENERIC;
- memcpy(new_inv, &copy, sizeof(invoice));
+ memops::copy(new_inv, &copy, sizeof(invoice));
if (!list_append(&g_administration.invoices, new_inv)) {
return A_ERR_GENERIC;
@@ -1648,15 +1645,15 @@ invoice administration::invoice_create_copy(invoice* inv)
invoice new_inv = administration::invoice_create_empty();
list_t billing_items = new_inv.billing_items;
- memcpy((void*)&new_inv, (void*)inv, sizeof(invoice));
+ memops::copy((void*)&new_inv, (void*)inv, sizeof(invoice));
new_inv.billing_items = billing_items;
list_iterator_start(&inv->billing_items);
while (list_iterator_hasnext(&inv->billing_items)) {
billing_item* c = (billing_item *)list_iterator_next(&inv->billing_items);
- billing_item* item_copy = (billing_item*)malloc(sizeof(billing_item));
- memcpy(item_copy, c, sizeof(billing_item));
+ billing_item* item_copy = (billing_item*)memops::alloc(sizeof(billing_item));
+ memops::copy(item_copy, c, sizeof(billing_item));
list_append(&new_inv.billing_items, item_copy);
}
list_iterator_stop(&inv->billing_items);
@@ -1886,7 +1883,7 @@ a_err administration::billing_item_remove_from_invoice(invoice* invoice, billing
if (strcmp(c->id, item.id) == 0) {
list_iterator_stop(&invoice->billing_items);
if (list_delete(&invoice->billing_items, c) != 0) return A_ERR_GENERIC;
- free(c);
+ memops::unalloc(c);
return A_ERR_SUCCESS;
}
}
@@ -1902,7 +1899,7 @@ a_err administration::billing_item_update_in_invoice(invoice* invoice, billing_i
billing_item* c = (billing_item *)list_iterator_next(&invoice->billing_items);
if (strcmp(c->id, item.id) == 0) {
- memcpy(c, &item, sizeof(billing_item));
+ memops::copy(c, &item, sizeof(billing_item));
list_iterator_stop(&invoice->billing_items);
administration_recalculate_billing_item_totals(c);
@@ -1928,10 +1925,10 @@ a_err administration::billing_item_import_to_invoice(invoice* invoice, billing_i
{
if (administration::billing_item_count(invoice) >= MAX_BILLING_ITEMS) return A_ERR_MAX_ITEMS_REACHED;
- billing_item* tb = (billing_item*)malloc(sizeof(billing_item));
+ billing_item* tb = (billing_item*)memops::alloc(sizeof(billing_item));
if (!tb) return A_ERR_GENERIC;
- memcpy(tb, &item, sizeof(billing_item));
+ memops::copy(tb, &item, sizeof(billing_item));
administration_recalculate_billing_item_totals(tb);
if (!list_append(&invoice->billing_items, tb)) {
@@ -1946,10 +1943,10 @@ a_err administration::billing_item_add_to_invoice(invoice* invoice, billing_item
{
if (administration::billing_item_count(invoice) >= MAX_BILLING_ITEMS) return A_ERR_MAX_ITEMS_REACHED;
- billing_item* tb = (billing_item*)malloc(sizeof(billing_item));
+ billing_item* tb = (billing_item*)memops::alloc(sizeof(billing_item));
if (!tb) return A_ERR_GENERIC;
- memcpy(tb, &item, sizeof(billing_item));
+ memops::copy(tb, &item, sizeof(billing_item));
strops::format(tb->id, sizeof(tb->id), "B/%d", create_id());
strops::copy(tb->currency, invoice->currency, MAX_LEN_CURRENCY); // Set billing item currency to invoice currency.
diff --git a/src/administration_reader.cpp b/src/administration_reader.cpp
index e39ae8c..73fc788 100644
--- a/src/administration_reader.cpp
+++ b/src/administration_reader.cpp
@@ -14,15 +14,13 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#include <malloc.h>
-#include <stdio.h>
-#include <stdint.h>
#include <zip.h>
#include <xml.h>
#include <time.h>
#include "logger.hpp"
#include "strops.hpp"
+#include "memops.hpp"
#include "administration_reader.hpp"
#include "administration_writer.hpp"
#include "tinyfiledialogs.h"
@@ -79,7 +77,7 @@ bool administration_reader::open_existing(char* file_path)
if (isdir) continue;
unsigned long long size = zip_entry_size(zip);
- char* buffer = (char*)malloc(size+1);
+ char* buffer = (char*)memops::alloc(size+1);
memset(buffer, 0, size+1);
zip_entry_read(zip, (void**)&buffer, (size_t*)&size);
@@ -110,7 +108,7 @@ bool administration_reader::open_existing(char* file_path)
administration_reader::import_invoice(buffer, (size_t)size);
}
- free(buffer);
+ memops::unalloc(buffer);
}
zip_entry_close(zip);
}
@@ -245,7 +243,7 @@ bool administration_reader::read_invoice_from_xml(invoice* result, char* buffer,
administration::billing_item_import_to_invoice(&data, bi);
}
- free(child_name);
+ memops::unalloc(child_name);
}
*result = data;
diff --git a/src/administration_writer.cpp b/src/administration_writer.cpp
index 040b842..f7069a6 100644
--- a/src/administration_writer.cpp
+++ b/src/administration_writer.cpp
@@ -14,13 +14,11 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#define _CRT_SECURE_NO_WARNINGS
-
#include <zip.h>
#include <xml.h>
-#include <stdlib.h>
#include <threads.h>
+#include "memops.hpp"
#include "logger.hpp"
#include "ui.hpp"
#include "locales.hpp"
@@ -94,9 +92,9 @@ 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*)malloc(buf_length);
+ char* file_content = (char*)memops::alloc(buf_length);
memset(file_content, 0, buf_length);
- memcpy(file_content, template_str, template_size);
+ memops::copy(file_content, template_str, template_size);
*buf_size = (int)buf_length;
return file_content;
}
@@ -311,7 +309,7 @@ static void _add_document_to_zip(invoice* inv)
long sz = ftell(orig_file);
fseek(orig_file, 0, SEEK_SET);
- char* file_copy = (char*)malloc(sz);
+ char* file_copy = (char*)memops::alloc(sz);
fread(file_copy, sz, 1, orig_file);
file_copy[sz-1] = 0;
@@ -325,7 +323,7 @@ static void _add_document_to_zip(invoice* inv)
logger::error("ERROR: failed to make copy of original document '%s'.", doc->original_path);
}
- free(file_copy);
+ memops::unalloc(file_copy);
}
}
@@ -335,9 +333,9 @@ bool administration_writer::save_invoice_blocking(invoice inv)
bool result = 1;
int buf_length = 150000; // Ballpark file content size.
- char* file_content = (char*)malloc(buf_length);
+ char* file_content = (char*)memops::alloc(buf_length);
memset(file_content, 0, buf_length);
- memcpy(file_content, file_template::peppol_invoice_template, strlen(file_template::peppol_invoice_template));
+ memops::copy(file_content, file_template::peppol_invoice_template, strlen(file_template::peppol_invoice_template));
struct tm *tm_info = 0;
char date_buffer[11]; // "YYYY-MM-DD" + null terminator
@@ -409,11 +407,11 @@ bool administration_writer::save_invoice_blocking(invoice inv)
// Tax breakdown
strops::replace_float(file_content, buf_length, "{{TOTAL_TAX_AMOUNT}}", inv.tax, 2);
{ // Create tax subtotal list.
- tax_rate* tax_rate_buffer = (tax_rate*)malloc(sizeof(tax_rate)*administration::billing_item_count(&inv));
+ tax_rate* tax_rate_buffer = (tax_rate*)memops::alloc(sizeof(tax_rate)*administration::billing_item_count(&inv));
u32 tax_rate_count = administration::invoice_get_tax_rates(&inv, tax_rate_buffer);
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*)malloc(tax_subtotal_list_buffer_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);
u32 tax_subtotal_list_buffer_cursor = 0;
@@ -432,7 +430,7 @@ bool administration_writer::save_invoice_blocking(invoice inv)
strops::replace_float(tax_entry_file_content, tax_entry_buf_length, "{{TAX_PERCENT}}", tax_rate_buffer[i].rate, 2);
u32 content_len = (u32)strlen(tax_entry_file_content);
- memcpy(tax_subtotal_list_buffer+tax_subtotal_list_buffer_cursor, tax_entry_file_content, content_len);
+ memops::copy(tax_subtotal_list_buffer+tax_subtotal_list_buffer_cursor, tax_entry_file_content, content_len);
tax_subtotal_list_buffer_cursor += content_len;
}
@@ -440,8 +438,8 @@ bool administration_writer::save_invoice_blocking(invoice inv)
strops::replace(file_content, buf_length, "{{TAX_SUBTOTAL_LIST}}", tax_subtotal_list_buffer);
- free(tax_subtotal_list_buffer);
- free(tax_rate_buffer);
+ memops::unalloc(tax_subtotal_list_buffer);
+ memops::unalloc(tax_rate_buffer);
}
// Totals
@@ -452,11 +450,11 @@ bool administration_writer::save_invoice_blocking(invoice inv)
// Invoice lines
{
- billing_item* billing_item_buffer = (billing_item*)malloc(sizeof(billing_item) * administration::billing_item_count(&inv));
+ billing_item* billing_item_buffer = (billing_item*)memops::alloc(sizeof(billing_item) * administration::billing_item_count(&inv));
u32 billing_item_count = administration::billing_item_get_all_for_invoice(&inv, billing_item_buffer);
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*)malloc(billing_item_list_buffer_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);
u32 billing_item_list_buffer_cursor = 0;
@@ -492,7 +490,7 @@ bool administration_writer::save_invoice_blocking(invoice inv)
strops::replace_float(billing_item_file_content, billing_item_buf_length, "{{DISCOUNT_TOTAL}}", bi.allowance, 2);
u32 content_len = (u32)strlen(billing_item_file_content);
- memcpy(billing_item_list_buffer+billing_item_list_buffer_cursor, billing_item_file_content, content_len);
+ memops::copy(billing_item_list_buffer+billing_item_list_buffer_cursor, billing_item_file_content, content_len);
billing_item_list_buffer_cursor += content_len;
}
@@ -500,8 +498,8 @@ bool administration_writer::save_invoice_blocking(invoice inv)
billing_item_list_buffer[billing_item_list_buffer_cursor] = 0;
strops::replace(file_content, buf_length, "{{INVOICE_LINE_LIST}}", billing_item_list_buffer);
- free(billing_item_list_buffer);
- free(billing_item_buffer);
+ memops::unalloc(billing_item_list_buffer);
+ memops::unalloc(billing_item_buffer);
}
// Dates
@@ -523,7 +521,7 @@ bool administration_writer::save_invoice_blocking(invoice inv)
if (!xml_parse_document((uint8_t*)file_content, final_length)) result = 0;
else if (!write_to_zip(final_path, file_content, final_length)) result = 0;
- free(file_content);
+ memops::unalloc(file_content);
if (result) logger::info("Saved invoice '%s' in %.3fms.", inv.sequential_number, STOPWATCH_TIME);
else logger::error("Failed to save invoice '%s'.", inv.sequential_number);
@@ -536,7 +534,7 @@ static bool save_all_invoices_blocking()
bool result = 1;
u32 num_invoices = administration::invoice_count();
u32 buffer_size = sizeof(invoice) * num_invoices;
- invoice* invoice_buffer = (invoice*)malloc(buffer_size);
+ invoice* invoice_buffer = (invoice*)memops::alloc(buffer_size);
num_invoices = administration::invoice_get_all(invoice_buffer);
for (u32 i = 0; i < num_invoices; i++) {
@@ -544,7 +542,7 @@ static bool save_all_invoices_blocking()
if (!administration_writer::save_invoice_blocking(c)) result = 0;
}
- free(invoice_buffer);
+ memops::unalloc(invoice_buffer);
return result;
}
@@ -582,7 +580,7 @@ bool administration_writer::save_project_blocking(project project)
if (!xml_parse_document((uint8_t*)file_content, final_length)) result = 0;
else if (!write_to_zip(final_path, file_content, final_length)) result = 0;
- free(file_content);
+ memops::unalloc(file_content);
if (result) logger::info("Saved project '%s' in %.3fms.", project.description, STOPWATCH_TIME);
else logger::error("Failed to save project '%s'.", project.description);
@@ -595,7 +593,7 @@ static bool save_all_projects_blocking()
bool result = 1;
u32 num_projects = administration::project_count();
u32 buffer_size = sizeof(project) * num_projects;
- project* project_buffer = (project*)malloc(buffer_size);
+ project* project_buffer = (project*)memops::alloc(buffer_size);
num_projects = administration::project_get_all(project_buffer);
for (u32 i = 0; i < num_projects; i++) {
@@ -603,7 +601,7 @@ static bool save_all_projects_blocking()
if (!administration_writer::save_project_blocking(c)) result = 0;
}
- free(project_buffer);
+ memops::unalloc(project_buffer);
return result;
}
@@ -630,7 +628,7 @@ bool administration_writer::save_cost_center_blocking(cost_center cost)
if (!xml_parse_document((uint8_t*)file_content, final_length)) result = 0;
else if (!write_to_zip(final_path, file_content, final_length)) result = 0;
- free(file_content);
+ memops::unalloc(file_content);
if (result) logger::info("Saved cost center '%s' in %.3fms.", cost.code, STOPWATCH_TIME);
else logger::error("Failed to save cost center '%s'.", cost.code);
@@ -643,7 +641,7 @@ bool administration_writer::save_all_cost_centers_blocking()
bool result = 1;
u32 num_costcenters = administration::cost_center_count();
u32 buffer_size = sizeof(cost_center) * num_costcenters;
- cost_center* costcenter_buffer = (cost_center*)malloc(buffer_size);
+ cost_center* costcenter_buffer = (cost_center*)memops::alloc(buffer_size);
num_costcenters = administration::cost_center_get_all(costcenter_buffer);
for (u32 i = 0; i < num_costcenters; i++) {
@@ -651,7 +649,7 @@ bool administration_writer::save_all_cost_centers_blocking()
if (!administration_writer::save_cost_center_blocking(c)) result = 0;
}
- free(costcenter_buffer);
+ memops::unalloc(costcenter_buffer);
return result;
}
@@ -679,7 +677,7 @@ bool administration_writer::save_tax_rate_blocking(tax_rate rate)
if (!xml_parse_document((uint8_t*)file_content, final_length)) result = 0;
else if (!write_to_zip(final_path, file_content, final_length)) result = 0;
- free(file_content);
+ memops::unalloc(file_content);
if (result) logger::info("Saved tax rate '%s/%.1f' in %.3fms.", rate.country_code, rate.rate, STOPWATCH_TIME);
else logger::error("Failed to save tax rate '%s/%.1f'.", rate.country_code, rate.rate);
@@ -692,7 +690,7 @@ bool administration_writer::save_all_tax_rates_blocking()
//// Get all data.
u32 num_rates = administration::tax_rate_count();
u32 buffer_size = sizeof(tax_rate) * num_rates;
- tax_rate* rate_buffer = (tax_rate*)malloc(buffer_size);
+ tax_rate* rate_buffer = (tax_rate*)memops::alloc(buffer_size);
num_rates = administration::tax_rate_get_all(rate_buffer);
bool result = 1;
@@ -702,7 +700,7 @@ bool administration_writer::save_all_tax_rates_blocking()
if (!administration_writer::save_tax_rate_blocking(c)) result = 0;
}
- free(rate_buffer);
+ memops::unalloc(rate_buffer);
return result;
}
@@ -739,7 +737,7 @@ bool administration_writer::save_contact_blocking(contact c)
if (!xml_parse_document((uint8_t*)file_content, final_length)) result = 0;
else if (!write_to_zip(final_path, file_content, final_length)) result = 0;
- free(file_content);
+ memops::unalloc(file_content);
if (result) logger::info("Saved contact '%s' in %.3fms.", c.name, STOPWATCH_TIME);
else logger::error("Failed to save contact '%s'.", c.name);
@@ -752,7 +750,7 @@ static bool save_all_contacts_blocking()
//// Get all data.
u32 num_contacts = administration::contact_count();
u32 buffer_size = sizeof(contact) * num_contacts;
- contact* contact_buffer = (contact*)malloc(buffer_size);
+ contact* contact_buffer = (contact*)memops::alloc(buffer_size);
num_contacts = administration::contact_get_all(contact_buffer);
bool result = 1;
@@ -766,7 +764,7 @@ static bool save_all_contacts_blocking()
if (!administration_writer::save_contact_blocking(c)) result = 0;
}
- free(contact_buffer);
+ memops::unalloc(contact_buffer);
return result;
}
@@ -794,7 +792,7 @@ bool administration_writer::save_all_administration_info_blocking()
if (!xml_parse_document((uint8_t*)file_content, final_length)) result = 0;
else if (!write_to_zip(ADMIN_FILE_INFO, file_content, final_length)) result = 0;
- free(file_content);
+ memops::unalloc(file_content);
if (result) logger::info("Saved administration info in %.3fms.", STOPWATCH_TIME);
else logger::error("Failed to save administration info.");
diff --git a/src/ai_providers/DeepSeek.cpp b/src/ai_providers/DeepSeek.cpp
index 4dd4e0a..a1857e9 100644
--- a/src/ai_providers/DeepSeek.cpp
+++ b/src/ai_providers/DeepSeek.cpp
@@ -14,15 +14,10 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#define _CRT_SECURE_NO_WARNINGS
-
-#include <fstream>
-#include <iostream>
-#include <string>
-
#define CPPHTTPLIB_OPENSSL_SUPPORT
#include "httplib.h"
#include "strops.hpp"
+#include "memops.hpp"
#include "logger.hpp"
#include "importer.hpp"
@@ -41,7 +36,7 @@ static bool _DeepSeek_query_with_file(char* query, size_t query_length, char* fi
//cli.enable_server_certificate_verification(false);
//char* query_escaped = strops::prep_str_for_json(query, query_length);
- //free(query); // TODO why??
+ //memops::unalloc(query); // TODO why??
size_t file_size = strlen(query_buffer);
sprintf(query_buffer + file_size, "%s", query);
@@ -49,7 +44,7 @@ static bool _DeepSeek_query_with_file(char* query, size_t query_length, char* fi
char* query_escaped = strops::prep_str_for_json(query_buffer, strlen(query_buffer));
size_t body_size = file_size + QUERY_BUFFER_SIZE;
- char* body = (char*)malloc(body_size);
+ char* body = (char*)memops::alloc(body_size);
strops::format(body, body_size,
"{\"model\":\"deepseek-reasoner\", \"messages\": [ { \"role\": \"user\", \"content\": \"%s\" } ] }", query_escaped);
@@ -59,7 +54,7 @@ static bool _DeepSeek_query_with_file(char* query, size_t query_length, char* fi
headers.insert(std::make_pair("Accept", "application/json"));
httplib::Result res = cli.Post("/chat/completions", headers, body, "application/json");
- free(body);
+ memops::unalloc(body);
if (!res || res->status != 200) {
logger::error("ERROR Failed to query API.");
@@ -68,7 +63,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*)malloc(100000);
+ *response = (char*)memops::alloc(100000);
memset(*response, 0, 100000);
strncpy(*response, response_body, 100000);
@@ -95,7 +90,7 @@ static bool _DeepSeek_upload_file(char* file_path, char* file_id, size_t file_id
fseek(orig_file, 0, SEEK_SET);
size_t buffer_size = sz + QUERY_BUFFER_SIZE;
- char* file_content_buffer = (char*)malloc(buffer_size);
+ char* file_content_buffer = (char*)memops::alloc(buffer_size);
memset(file_content_buffer, 0, buffer_size);
query_buffer = file_content_buffer;
diff --git a/src/ai_providers/openAI.cpp b/src/ai_providers/openAI.cpp
index c4526ef..b55f191 100644
--- a/src/ai_providers/openAI.cpp
+++ b/src/ai_providers/openAI.cpp
@@ -14,14 +14,9 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#define _CRT_SECURE_NO_WARNINGS
-
-#include <fstream>
-#include <iostream>
-#include <string>
-
#define CPPHTTPLIB_OPENSSL_SUPPORT
#include "httplib.h"
+#include "memops.hpp"
#include "strops.hpp"
#include "logger.hpp"
#include "importer.hpp"
@@ -35,10 +30,10 @@ static bool _openAI_query_with_file(char* query, size_t query_length, char* file
//cli.enable_server_certificate_verification(false);
char* query_escaped = strops::prep_str_for_json(query, query_length);
- free(query);
+ memops::unalloc(query);
size_t body_size = query_length + 200;
- char* body = (char*)malloc(body_size);
+ char* body = (char*)memops::alloc(body_size);
strops::format(body, body_size,
"{\"model\":\"gpt-5-nano\", \"input\": [ { \"role\": \"user\", \"content\": [ { \"type\": \"input_file\", \"file_id\": \"%s\" }, "
"{ \"type\": \"input_text\", \"text\": \"%s\" } ] } ] }", file_id, query_escaped);
@@ -47,7 +42,7 @@ static bool _openAI_query_with_file(char* query, size_t query_length, char* file
headers.insert(std::make_pair("Authorization", std::string("Bearer ") + api_key));
httplib::Result res = cli.Post("/v1/responses", headers, body, "application/json");
- free(body);
+ memops::unalloc(body);
if (!res || res->status != 200) {
logger::error("ERROR Failed to query API.");
@@ -56,14 +51,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*)malloc(100000);
+ *response = (char*)memops::alloc(100000);
memset(*response, 0, 100000);
strncpy(*response, response_body, 100000);
strops::get_json_value(*response, "text", *response, 100000);
*response = strops::unprep_str_from_json(*response);
#else
- *response = (char*)malloc(100000);
+ *response = (char*)memops::alloc(100000);
memset(*response, 0, 100000);
strops::copy(*response, "<Invoice xmlns=\"urn:oasis:names:specification:ubl:schema:xsd:Invoice-2\" xmlns:cac=\"urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2\" xmlns:cbc=\"urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2\"> <cbc:CustomizationID>urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0</cbc:CustomizationID> <cbc:ProfileID>urn:fdc:peppol.eu:2017:poacc:billing:01:1.0</cbc:ProfileID> <cbc:ID>492043632</cbc:ID> <cbc:IssueDate>2024-09-01</cbc:IssueDate> <cbc:DueDate>2024-09-01</cbc:DueDate> <cbc:InvoiceTypeCode>380</cbc:InvoiceTypeCode> <cbc:DocumentCurrencyCode>USD</cbc:DocumentCurrencyCode> <cac:DespatchDocumentReference> <cbc:ID>Final invoice</cbc:ID> </cac:DespatchDocumentReference> <cac:AdditionalDocumentReference> <cbc:ID></cbc:ID> <cbc:DocumentDescription></cbc:DocumentDescription> </cac:AdditionalDocumentReference> <cac:OrderReference> <cbc:ID></cbc:ID> </cac:OrderReference> <cac:ProjectReference> <cbc:ID>do:team:67840ecb-44e2-472e-bc45-801bd4e1f1fe</cbc:ID> </cac:ProjectReference> <cbc:AccountingCost></cbc:AccountingCost> <cac:AccountingSupplierParty> <cac:Party> <cbc:EndpointID schemeID=""></cbc:EndpointID> <cac:PartyIdentification> <cbc:ID schemeID=\"ZZZ\"></cbc:ID> </cac:PartyIdentification> <cac:PartyName> <cbc:Name>DigitalOcean LLC</cbc:Name> </cac:PartyName> <cac:PostalAddress> <cbc:StreetName>101 Avenue of the Americas</cbc:StreetName> <cbc:AdditionalStreetName>2nd Floor</cbc:AdditionalStreetName> <cbc:CityName>New York</cbc:CityName> <cbc:PostalZone>10013</cbc:PostalZone> <cbc:CountrySubentity>NY</cbc:CountrySubentity> <cac:Country> <cbc:IdentificationCode>US</cbc:IdentificationCode> </cac:Country> </cac:PostalAddress> <cac:PartyTaxScheme> <cbc:CompanyID>EU528002224</cbc:CompanyID> <cac:TaxScheme> <cbc:ID>VAT</cbc:ID> </cac:TaxScheme> </cac:PartyTaxScheme> <cac:PartyLegalEntity> <cbc:RegistrationName>DigitalOcean LLC</cbc:RegistrationName> </cac:PartyLegalEntity> <cac:Contact> <cbc:Name></cbc:Name> <cbc:Telephone></cbc:Telephone> <cbc:ElectronicMail></cbc:ElectronicMail> </cac:Contact> </cac:Party> </cac:AccountingSupplierParty> <cac:AccountingCustomerParty> <cac:Party> <cbc:EndpointID schemeID=""></cbc:EndpointID> <cac:PartyIdentification> <cbc:ID schemeID=\"ZZZ\"></cbc:ID> </cac:PartyIdentification> <cac:PartyName> <cbc:Name>My Team</cbc:Name> </cac:PartyName> <cac:PostalAddress> <cbc:StreetName>Keerderstraat 81</cbc:StreetName> <cbc:AdditionalStreetName></cbc:AdditionalStreetName> <cbc:CityName>Maastricht</cbc:CityName> <cbc:PostalZone>6226 XW</cbc:PostalZone> <cbc:CountrySubentity>LI</cbc:CountrySubentity> <cac:Country> <cbc:IdentificationCode>NL</cbc:IdentificationCode> </cac:Country> </cac:PostalAddress> <cac:PartyTaxScheme> <cbc:CompanyID></cbc:CompanyID> <cac:TaxScheme> <cbc:ID>VAT</cbc:ID> </cac:TaxScheme> </cac:PartyTaxScheme> <cac:PartyLegalEntity> <cbc:RegistrationName></cbc:RegistrationName> </cac:PartyLegalEntity> <cac:Contact> <cbc:Name></cbc:Name> <cbc:Telephone></cbc:Telephone> <cbc:ElectronicMail>aldrikboy@gmail.com</cbc:ElectronicMail> </cac:Contact> </cac:Party> </cac:AccountingCustomerParty> <cac:Delivery> <cbc:ActualDeliveryDate></cbc:ActualDeliveryDate> <cac:DeliveryLocation> <cac:Address> <cbc:StreetName></cbc:StreetName> <cbc:AdditionalStreetName></cbc:AdditionalStreetName> <cbc:CityName></cbc:CityName> <cbc:PostalZone></cbc:PostalZone> <cbc:CountrySubentity></cbc:CountrySubentity> <cac:Country> <cbc:IdentificationCode></cbc:IdentificationCode> </cac:Country> </cac:Address> </cac:DeliveryLocation> <cac:DeliveryParty> <cac:PartyName> <cbc:Name></cbc:Name> </cac:PartyName> </cac:DeliveryParty> </cac:Delivery> <cac:PaymentMeans> <cbc:PaymentMeansCode></cbc:PaymentMeansCode> <cbc:PaymentID>492043632</cbc:PaymentID> <cac:PayeeFinancialAccount> <cbc:ID></cbc:ID> <cbc:Name></cbc:Name> <cac:FinancialInstitutionBranch> <cac:FinancialInstitution> <cbc:ID></cbc:ID> </cac:FinancialInstitution> </cac:FinancialInstitutionBranch> </cac:PayeeFinancialAccount> <cac:PayerFinancialAccount> <cbc:ID></cbc:ID> </cac:PayerFinancialAccount> </cac:PaymentMeans> <cac:TaxTotal> <cbc:TaxAmount currencyID=\"USD\">3.49</cbc:TaxAmount> <cac:TaxSubtotal> <cbc:TaxableAmount currencyID=\"USD\">15.60</cbc:TaxableAmount> <cbc:TaxAmount currencyID=\"USD\">3.28</cbc:TaxAmount> <cac:TaxCategory> <cac:TaxScheme> <cbc:ID>VAT</cbc:ID> </cac:TaxScheme> </cac:TaxCategory> </cac:TaxSubtotal> <cac:TaxSubtotal> <cbc:TaxableAmount currencyID=\"USD\">1.00</cbc:TaxableAmount> <cbc:TaxAmount currencyID=\"USD\">0.21</cbc:TaxAmount> <cac:TaxCategory> <cac:TaxScheme> <cbc:ID>VAT</cbc:ID> </cac:TaxScheme> </cac:TaxCategory> </cac:TaxSubtotal> </cac:TaxTotal> <cac:LegalMonetaryTotal> <cbc:LineExtensionAmount currencyID=\"USD\">16.60</cbc:LineExtensionAmount> <cbc:TaxExclusiveAmount currencyID=\"USD\">16.60</cbc:TaxExclusiveAmount> <cbc:TaxInclusiveAmount currencyID=\"USD\">20.09</cbc:TaxInclusiveAmount> <cbc:PayableAmount currencyID=\"USD\">20.09</cbc:PayableAmount> </cac:LegalMonetaryTotal> <cac:InvoiceLine> <cbc:ID>1</cbc:ID> <cbc:InvoicedQuantity unitCode=""></cbc:InvoicedQuantity> <cbc:LineExtensionAmount currencyID=\"USD\">16.60</cbc:LineExtensionAmount> <cac:AllowanceCharge> <cbc:ChargeIndicator>false</cbc:ChargeIndicator> <cbc:AllowanceChargeReason>Discount</cbc:AllowanceChargeReason> <cbc:MultiplierFactorNumeric></cbc:MultiplierFactorNumeric> <cbc:Amount currencyID=\"USD\"></cbc:Amount> <cbc:BaseAmount currencyID=\"USD\"></cbc:BaseAmount> </cac:AllowanceCharge> <cac:Item> <cbc:Name>Product Usage Charges</cbc:Name> <cac:AdditionalItemProperty> <cbc:Name>Internal Tax Rate ID</cbc:Name> <cbc:Value></cbc:Value> </cac:AdditionalItemProperty> <cac:ClassifiedTaxCategory> <cbc:ID></cbc:ID> <cbc:Percent></cbc:Percent> <cac:TaxScheme> <cbc:ID>VAT</cbc:ID> </cac:TaxScheme> </cac:ClassifiedTaxCategory> </cac:Item> <cac:Price> <cbc:PriceAmount currencyID=\"USD\"></cbc:PriceAmount> </cac:Price> </cac:InvoiceLine></Invoice>", 100000);
#endif
@@ -108,7 +103,7 @@ static bool _openAI_upload_file(char* file_path, char* file_id, size_t file_id_l
size_t part_size = 64000000; // 64mb
logger::info("Created upload %s with part size %zu.", upload_id, part_size);
- char *buffer = (char*)malloc(part_size);
+ char *buffer = (char*)memops::alloc(part_size);
char completion_body[1048];
strops::format(completion_body, sizeof(completion_body), "{\"part_ids\": [");
@@ -135,7 +130,7 @@ static bool _openAI_upload_file(char* file_path, char* file_id, size_t file_id_l
if (!part_res || part_res->status != 200) {
logger::error("Failed to upload part %d.", part_number);
logger::error(part_res->body.c_str());
- free(buffer);
+ memops::unalloc(buffer);
fclose(orig_file);
return 0;
}
@@ -152,7 +147,7 @@ static bool _openAI_upload_file(char* file_path, char* file_id, size_t file_id_l
strops::format(completion_body+strlen(completion_body), sizeof(completion_body)-strlen(completion_body), "]}");
- free(buffer);
+ memops::unalloc(buffer);
fclose(orig_file);
// ---------- Step 3: Complete upload ----------
diff --git a/src/importer.cpp b/src/importer.cpp
index 8b5cc5c..23960b1 100644
--- a/src/importer.cpp
+++ b/src/importer.cpp
@@ -14,21 +14,17 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#define _CRT_SECURE_NO_WARNINGS
-
-#include <fstream>
-#include <iostream>
-#include <string>
#include <threads.h>
#define CPPHTTPLIB_OPENSSL_SUPPORT
#include "httplib.h"
#include "logger.hpp"
-#include "importer.hpp"
#include "strops.hpp"
-#include "administration_reader.hpp"
+#include "memops.hpp"
#include "locales.hpp"
+#include "importer.hpp"
#include "file_templates.hpp"
+#include "administration_reader.hpp"
extern importer::ai_provider_impl _chatgpt_api_provider;
extern importer::ai_provider_impl _deepseek_api_provider;
@@ -62,7 +58,7 @@ static int _ai_document_to_invoice_t(void *arg) {
request->status = importer::status::IMPORT_QUERYING;
size_t query_buffer_len = 50000;
- char* template_buffer = (char*)malloc(query_buffer_len);
+ char* template_buffer = (char*)memops::alloc(query_buffer_len);
memset(template_buffer, 0, query_buffer_len);
strncpy(template_buffer, file_template::peppol_invoice_template, query_buffer_len);
@@ -120,7 +116,7 @@ static int _ai_document_to_invoice_t(void *arg) {
// Set customer or supplier depending on incomming or outgoing.
contact my_info = administration::company_info_get();
- memcpy(&inv.customer, &my_info, sizeof(contact));
+ memops::copy(&inv.customer, &my_info, sizeof(contact));
strops::copy(inv.customer.id, MY_COMPANY_ID, MAX_LEN_ID);
// Project and cost centers cannot be interpreted from file so are set to 0.
@@ -140,8 +136,8 @@ static int _ai_document_to_invoice_t(void *arg) {
inv.delivered_at = inv.issued_at;
}
- free(template_buffer);
- free(response);
+ memops::unalloc(template_buffer);
+ memops::unalloc(response);
request->status = importer::status::IMPORT_DONE;
request->result = administration::invoice_create_copy(&inv);
@@ -150,7 +146,7 @@ static int _ai_document_to_invoice_t(void *arg) {
importer::invoice_request* importer::ai_document_to_invoice(char* file_path)
{
- importer::invoice_request* result = (importer::invoice_request*)malloc(sizeof(importer::invoice_request));
+ importer::invoice_request* result = (importer::invoice_request*)memops::alloc(sizeof(importer::invoice_request));
result->started_at = time(NULL);
result->error = I_ERR_SUCCESS;
result->status = importer::status::IMPORT_STARTING;
diff --git a/src/logger.cpp b/src/logger.cpp
index df0ae91..0035948 100644
--- a/src/logger.cpp
+++ b/src/logger.cpp
@@ -19,7 +19,7 @@
#include <time.h>
#include "timer.h"
-
+#include "memops.hpp"
#include "strops.hpp"
#include "logger.hpp"
@@ -54,7 +54,7 @@ namespace logger {
char tmp[logger::MAX_LEN_LOG_TXT];
strops::format(tmp, logger::MAX_LEN_LOG_TXT, "[%s] %s", time_buf, g_log.history[g_log.write_cursor]);
tmp[logger::MAX_LEN_LOG_TXT-1] = 0;
- memcpy(g_log.history[g_log.write_cursor], tmp, logger::MAX_LEN_LOG_TXT);
+ memops::copy(g_log.history[g_log.write_cursor], tmp, logger::MAX_LEN_LOG_TXT);
g_log.write_cursor++;
if (g_log.write_cursor >= logger::MAX_LEN_LOG_HISTORY) g_log.write_cursor = 0;
diff --git a/src/memops.cpp b/src/memops.cpp
new file mode 100644
index 0000000..09e592e
--- /dev/null
+++ b/src/memops.cpp
@@ -0,0 +1,40 @@
+/*
+* Copyright (c) 2025 Aldrik Ramaekers <aldrik.ramaekers@gmail.com>
+*
+* Permission to use, copy, modify, and/or distribute this software for any
+* purpose with or without fee is hereby granted, provided that the above
+* copyright notice and this permission notice appear in all copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+#include <stdlib.h>
+#include <malloc.h>
+
+#include "memops.hpp"
+
+void* memops::stack_alloc(size_t size)
+{
+ return alloca(size);
+}
+
+void* memops::alloc(size_t size)
+{
+ return malloc(size);
+}
+
+void memops::unalloc(void *ptr)
+{
+ free(ptr);
+}
+
+void* memops::copy(void* destination, const void* source, size_t num)
+{
+ return memcpy(destination, source, num);
+}
diff --git a/src/strops.cpp b/src/strops.cpp
index 6142c01..146a909 100644
--- a/src/strops.cpp
+++ b/src/strops.cpp
@@ -14,10 +14,10 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#include <stdlib.h>
#include <ctype.h>
#include <stdio.h>
+#include "memops.hpp"
#include "strops.hpp"
namespace strops {
@@ -36,7 +36,7 @@ namespace strops {
if (srclen > size)
srclen = size;
- memcpy(dst, src, srclen);
+ memops::copy(dst, src, srclen);
dst[srclen] = '\0';
return (srclen);
@@ -99,7 +99,7 @@ namespace strops {
skip_size = replace_len;
}
- memcpy(w, replace, copy_len);
+ memops::copy(w, replace, copy_len);
w += copy_len;
r += skip_size;
} else {
@@ -169,7 +169,7 @@ namespace strops {
{
if (!input) return NULL;
- char *result = (char*)malloc(buffer_size * 2 + 1);
+ char *result = (char*)memops::alloc(buffer_size * 2 + 1);
if (!result) return NULL;
const char *src = input;
diff --git a/src/ui/imgui_extensions.cpp b/src/ui/imgui_extensions.cpp
index 4e8270a..ee0bebb 100644
--- a/src/ui/imgui_extensions.cpp
+++ b/src/ui/imgui_extensions.cpp
@@ -1,7 +1,6 @@
-#include <stdlib.h>
-
#include "ui.hpp"
#include "strops.hpp"
+#include "memops.hpp"
#include "config.hpp"
#include "locales.hpp"
#include "administration.hpp"
@@ -225,7 +224,7 @@ namespace ImGui
for (int i = 0; i < autocomplete_count; i++)
{
- autocomplete_strings[i] = (char*)malloc(200);
+ autocomplete_strings[i] = (char*)memops::alloc(200);
strops::format(autocomplete_strings[i], 200, "%s (%s %s)", autocomplete_list[i].name, autocomplete_list[i].address.address1, autocomplete_list[i].address.address2);
}
@@ -234,19 +233,19 @@ namespace ImGui
if (autocomplete_index != -1)
{
- memcpy(buffer, &autocomplete_list[autocomplete_index], sizeof(contact));
+ memops::copy(buffer, &autocomplete_list[autocomplete_index], sizeof(contact));
}
for (int i = 0; i < autocomplete_count; i++)
{
- free(autocomplete_strings[i]);
+ memops::unalloc(autocomplete_strings[i]);
}
}
void FormCostCenterCombo(char* costcenter_id)
{
u32 costcenter_count = administration::cost_center_count();
- cost_center* buffer = (cost_center*) malloc(sizeof(cost_center) * costcenter_count);
+ cost_center* buffer = (cost_center*) memops::alloc(sizeof(cost_center) * costcenter_count);
cost_center* selected_costcenter = NULL;
costcenter_count = administration::cost_center_get_all(buffer);
@@ -281,13 +280,13 @@ namespace ImGui
strops::copy(costcenter_id, buffer[selected_costcenter_index].id, MAX_LEN_ID);
}
- free(buffer);
+ memops::unalloc(buffer);
}
void FormProjectCombo(char* project_id)
{
u32 project_count = administration::project_count();
- project* buffer = (project*) malloc(sizeof(project) * project_count);
+ project* buffer = (project*) memops::alloc(sizeof(project) * project_count);
project* selected_project = NULL;
project_count = administration::project_get_all(buffer);
@@ -322,13 +321,13 @@ namespace ImGui
strops::copy(project_id, buffer[selected_project_index].id, MAX_LEN_ID);
}
- free(buffer);
+ memops::unalloc(buffer);
}
void FormTaxRateCombo(char* tax_rate_id, char* orig_country, char* dest_country, bool has_error)
{
u32 tax_rate_count = administration::tax_rate_count();
- tax_rate* buffer = (tax_rate*) malloc(sizeof(tax_rate) * tax_rate_count);
+ tax_rate* buffer = (tax_rate*) memops::alloc(sizeof(tax_rate) * tax_rate_count);
tax_rate* selected_tax_rate = NULL;
char* tax_country_codes[2] = {orig_country, dest_country};
@@ -394,7 +393,7 @@ namespace ImGui
strops::copy(tax_rate_id, buffer[selected_tax_rate_index].id, MAX_LEN_ID);
}
- free(buffer);
+ memops::unalloc(buffer);
}
bool FormCurrencyCombo(char* currency)
diff --git a/src/ui/ui_earnings.cpp b/src/ui/ui_earnings.cpp
index 1ceabbe..8f08bcb 100644
--- a/src/ui/ui_earnings.cpp
+++ b/src/ui/ui_earnings.cpp
@@ -14,24 +14,24 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#include <stdlib.h>
#include "ui.hpp"
#include "imgui.h"
-#include "administration.hpp"
+#include "memops.hpp"
#include "locales.hpp"
+#include "administration.hpp"
income_statement* statement = 0;
void ui::setup_earnings()
{
- statement = (income_statement*)malloc(sizeof(income_statement));
+ statement = (income_statement*)memops::alloc(sizeof(income_statement));
administration::create_income_statement(statement);
}
void ui::destroy_earnings()
{
- free(statement);
+ memops::unalloc(statement);
}
void ui::draw_earnings()
diff --git a/src/ui/ui_expenses.cpp b/src/ui/ui_expenses.cpp
index 8812273..e22b5b1 100644
--- a/src/ui/ui_expenses.cpp
+++ b/src/ui/ui_expenses.cpp
@@ -14,20 +14,17 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#define _CRT_SECURE_NO_WARNINGS
-#include <stdio.h>
#include <time.h>
+#include <ImGuiDatePicker/ImGuiDatePicker.hpp>
-#include "ImGuiDatePicker/ImGuiDatePicker.hpp"
-//#include "tinyfiledialogs/tinyfiledialogs.h"
-
-#include "strops.hpp"
#include "ui.hpp"
#include "imgui.h"
-#include "administration.hpp"
-#include "administration_writer.hpp"
+#include "memops.hpp"
+#include "strops.hpp"
#include "locales.hpp"
#include "importer.hpp"
+#include "administration.hpp"
+#include "administration_writer.hpp"
static importer::invoice_request* active_import_request = 0;
@@ -43,7 +40,7 @@ void draw_invoice_items_form(invoice* invoice);
void ui::destroy_expenses()
{
- free(invoice_items_buffer);
+ memops::unalloc(invoice_items_buffer);
}
void ui::setup_expenses()
@@ -58,7 +55,7 @@ void ui::setup_expenses()
active_invoice = administration::invoice_create_empty();
u32 invoice_items_count = MAX_BILLING_ITEMS;
- invoice_items_buffer = (billing_item*)malloc(sizeof(billing_item) * invoice_items_count);
+ invoice_items_buffer = (billing_item*)memops::alloc(sizeof(billing_item) * invoice_items_count);
}
static void draw_expense_form(invoice* buffer, bool viewing_only = false)
diff --git a/src/ui/ui_invoices.cpp b/src/ui/ui_invoices.cpp
index 4dd44e8..850c9a3 100644
--- a/src/ui/ui_invoices.cpp
+++ b/src/ui/ui_invoices.cpp
@@ -14,19 +14,16 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#define _CRT_SECURE_NO_WARNINGS
-#include <stdio.h>
#include <time.h>
+#include <ImGuiDatePicker/ImGuiDatePicker.hpp>
-#include "ImGuiDatePicker/ImGuiDatePicker.hpp"
-//#include "tinyfiledialogs/tinyfiledialogs.h"
-
-#include "strops.hpp"
#include "ui.hpp"
#include "imgui.h"
+#include "memops.hpp"
+#include "strops.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;
@@ -40,7 +37,7 @@ void draw_addressee_form_ex(delivery_info* buffer, bool viewing_only = false);
void ui::destroy_invoices()
{
- free(invoice_items_buffer);
+ memops::unalloc(invoice_items_buffer);
}
void ui::setup_invoices()
@@ -49,7 +46,7 @@ void ui::setup_invoices()
active_invoice = administration::invoice_create_empty();
u32 invoice_items_count = MAX_BILLING_ITEMS;
- invoice_items_buffer = (billing_item*)malloc(sizeof(billing_item) * invoice_items_count);
+ invoice_items_buffer = (billing_item*)memops::alloc(sizeof(billing_item) * invoice_items_count);
}
void draw_invoice_items_form(invoice* invoice)
diff --git a/src/ui/ui_settings.cpp b/src/ui/ui_settings.cpp
index 8177f07..dd59323 100644
--- a/src/ui/ui_settings.cpp
+++ b/src/ui/ui_settings.cpp
@@ -14,14 +14,14 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#include <stdlib.h>
-#include "strops.hpp"
#include "ui.hpp"
#include "imgui.h"
-#include "administration.hpp"
+#include "strops.hpp"
+#include "memops.hpp"
#include "locales.hpp"
#include "importer.hpp"
+#include "administration.hpp"
#include "administration_writer.hpp"
extern void draw_contact_form(contact* buffer, bool viewing_only = false);
@@ -39,8 +39,8 @@ static ai_service new_service;
void ui::destroy_settings()
{
- free(tax_rates);
- free(cost_centers);
+ memops::unalloc(tax_rates);
+ memops::unalloc(cost_centers);
}
void ui::setup_settings()
@@ -49,11 +49,11 @@ void ui::setup_settings()
company_info = administration::company_info_get();
tax_rate_count = administration::tax_rate_count();
- tax_rates = (tax_rate*)malloc(tax_rate_count * sizeof(tax_rate));
+ tax_rates = (tax_rate*)memops::alloc(tax_rate_count * sizeof(tax_rate));
administration::tax_rate_get_all(tax_rates);
cost_center_count = administration::cost_center_count();
- cost_centers = (cost_center*)malloc(cost_center_count * sizeof(cost_center));
+ cost_centers = (cost_center*)memops::alloc(cost_center_count * sizeof(cost_center));
administration::cost_center_get_all(cost_centers);
new_service = administration::get_ai_service();
diff --git a/tests/test_helper.cpp b/tests/test_helper.cpp
index b74916a..1dbb2b2 100644
--- a/tests/test_helper.cpp
+++ b/tests/test_helper.cpp
@@ -1,13 +1,9 @@
-#define _CRT_SECURE_NO_WARNINGS
-
-#include <stdlib.h>
-#include <malloc.h>
-
-#include "zip.h"
-#include "xml.h"
-#include "greatest.h"
-#include "timer.h"
+#include <zip.h>
+#include <xml.h>
+#include <greatest.h>
+#include <timer.h>
+#include "memops.hpp"
#include "strops.hpp"
#include "administration.hpp"
#include "administration_reader.hpp"
@@ -198,7 +194,7 @@ static bool _test_peppol_file(char* id)
{
struct xml_string* attr_name = xml_node_attribute_name(node, x);
size_t b_length = xml_string_length(attr_name);
- uint8_t* b_buffer = (uint8_t*)alloca((b_length + 1) * sizeof(uint8_t));
+ uint8_t* b_buffer = (uint8_t*)memops::stack_alloc((b_length + 1) * sizeof(uint8_t));
xml_string_copy(attr_name, b_buffer, b_length);
b_buffer[b_length] = 0;
@@ -206,7 +202,7 @@ static bool _test_peppol_file(char* id)
struct xml_string* attr_content = xml_node_attribute_content(node, x);
size_t a_length = xml_string_length(attr_content);
- uint8_t* a_buffer = (uint8_t*)alloca((a_length + 1) * sizeof(uint8_t));
+ uint8_t* a_buffer = (uint8_t*)memops::stack_alloc((a_length + 1) * sizeof(uint8_t));
xml_string_copy(attr_content, a_buffer, a_length);
a_buffer[a_length] = 0;