From 54103773365e06d6da8518d135c396949e683960 Mon Sep 17 00:00:00 2001 From: dam Date: Sun, 5 May 2024 04:19:06 +0100 Subject: Fixed memory leaks. --- modules/TUI/module.jai | 26 +++++++++++++------------- ttt.jai | 32 ++++++++++++++++++-------------- 2 files changed, 31 insertions(+), 27 deletions(-) diff --git a/modules/TUI/module.jai b/modules/TUI/module.jai index 3f824a4..dc9643c 100644 --- a/modules/TUI/module.jai +++ b/modules/TUI/module.jai @@ -511,17 +511,17 @@ read_input_line :: (count_limit: int, is_visible: bool = true) -> string, Key { // Draw preview. if is_visible { - append(*builder, tprint(Commands.SetCursorPosition, y, x)); + print_to_builder(*builder, Commands.SetCursorPosition, y, x); append(*builder, str); for chars_count..count_limit-1 append(*builder, " "); } else { - append(*builder, tprint(Commands.SetCursorPosition, y, x)); + print_to_builder(*builder, Commands.SetCursorPosition, y, x); for 1..chars_count append(*builder, "*"); for chars_count..count_limit-1 append(*builder, " "); } - append(*builder, tprint(Commands.SetCursorPosition, y, x+idx)); - write_string(builder_to_string(*builder)); + print_to_builder(*builder, Commands.SetCursorPosition, y, x+idx); + write_string(builder_to_string(*builder,, allocator = temporary_allocator)); // Process input key. key = get_key(); @@ -600,7 +600,7 @@ draw_box :: (x: int, y: int, width: int, height: int) { append(*builder, Commands.DrawingMode); // Draw top line - append(*builder, tprint(Commands.SetCursorPosition, y, x)); + print_to_builder(*builder, Commands.SetCursorPosition, y, x); append(*builder, Drawings.CornerTL); for 1..width-2 { append(*builder, Drawings.LineH); @@ -609,14 +609,14 @@ draw_box :: (x: int, y: int, width: int, height: int) { // Draw left and right sides. for idx: y+1..y+height-2 { - append(*builder, tprint(Commands.SetCursorPosition, idx, x)); + print_to_builder(*builder, Commands.SetCursorPosition, idx, x); append(*builder, Drawings.LineV); - append(*builder, tprint(Commands.SetCursorPosition, idx, x+width-1)); + print_to_builder(*builder, Commands.SetCursorPosition, idx, x+width-1); append(*builder, Drawings.LineV); } // Draw bottom line. - append(*builder, tprint(Commands.SetCursorPosition, y+height-1, x)); + print_to_builder(*builder, Commands.SetCursorPosition, y+height-1, x); append(*builder, Drawings.CornerBL); for 1..width-2 { append(*builder, Drawings.LineH); @@ -625,7 +625,7 @@ draw_box :: (x: int, y: int, width: int, height: int) { append(*builder, Commands.TextMode); - write_string(builder_to_string(*builder)); + write_string(builder_to_string(*builder,, allocator = temporary_allocator)); } clear_terminal :: inline () { @@ -647,7 +647,7 @@ get_terminal_size :: () -> width: int, height: int { // Expected response format: \e[8;;t // where is the number of rows and of columns. FORMAT :: "\e[8;;t"; - input := read_input(64, #char "t",, temporary_allocator); + input := read_input(64, #char "t",, allocator = temporary_allocator); // Discard head noise. while input.count >= 3 && (input[0] != FORMAT[0] || input[1] != FORMAT[1] || input[2] != FORMAT[2]) { @@ -663,7 +663,7 @@ get_terminal_size :: () -> width: int, height: int { input[0] == FORMAT[0] && input[1] == FORMAT[1] && input[2] == FORMAT[2] && input[input.count-1] == FORMAT[FORMAT.count-1], "Failed to query window size: invalid response."); - parts := split(input, ";",, temporary_allocator); + parts := split(input, ";",, allocator = temporary_allocator); rows = parse_int(*parts[1]); columns = parse_int(*parts[2]); } @@ -696,7 +696,7 @@ get_cursor_position :: () -> x: int, y: int { // Expected response format: \e[;R // where is the number of rows and of columns. FORMAT :: "\e[;R"; - input := read_input(64, #char "R"); + input := read_input(64, #char "R",, allocator = temporary_allocator); // Discard head noise. while input.count >= 2 && (input[0] != FORMAT[0] || input[1] != FORMAT[1]) { @@ -713,7 +713,7 @@ get_cursor_position :: () -> x: int, y: int { "Failed to query cursor position: invalid response."); advance(*input, 2); - parts := split(input, ";",, temporary_allocator); + parts := split(input, ";",, allocator = temporary_allocator); row := parse_int(*parts[0]); column := parse_int(*parts[1]); return column, row; diff --git a/ttt.jai b/ttt.jai index 0715544..929a736 100644 --- a/ttt.jai +++ b/ttt.jai @@ -590,12 +590,14 @@ load_database :: (db: *Database, path: string) -> success: bool { // Returns success. export_to_csv :: (db: Database, path: string) -> success: bool { assert(xx path, ASSERT_NOT_EMPTY, "path"); + + auto_release_temp(); builder: String_Builder; defer reset(*builder); CSV_HEADER :: string.[ "task", "sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday" ]; - print_to_builder(*builder, "%\n", join(..CSV_HEADER, separator = ",")); + print_to_builder(*builder, "%\n", join(..CSV_HEADER, separator = ",",, temporary_allocator)); buffer: [Task.name.count] u8; name: string = xx buffer; @@ -701,15 +703,16 @@ import_from_csv :: (db: *Database, path: string) -> bool { } { // Parse CSV lines. - auto_release_temp(); // TODO Needs to be tested. line := csv; while (true) { + auto_release_temp(); + line, success := consume_next_line(*csv); // line, success := next_line(*csv); if success == false break; task: Task; - csv_values := split(line, ",",, temporary_allocator); // TODO Temporary memory... if file is too big this may break. + csv_values := split(line, ",",, temporary_allocator); // Import task name. name_length := min(task.name.count, csv_values[0].count); @@ -891,6 +894,8 @@ update_layout :: () { draw_tui :: (db: *Database, layout: *Layout) { + // TODO During dirty_flag revamp...we may also start using the String_Builder. + adjust_first_day_of_week := int.[ (0 + FIRST_DAY_OF_WEEK) % NUM_WEEK_DAYS, (1 + FIRST_DAY_OF_WEEK) % NUM_WEEK_DAYS, @@ -990,7 +995,6 @@ draw_tui :: (db: *Database, layout: *Layout) { // Display up to rows allowed by the layout, or less if reached end of database. idx_stop := idx_start + (ifx layout_tasks_rows > db.tasks.count - idx_start then db.tasks.count - idx_start else layout_tasks_rows); for task_idx: idx_start..idx_stop-1 { - auto_release_temp(); // TODO Temporary memory being trashed?! task := *db.tasks[task_idx]; y += 1; x = 1; @@ -1138,7 +1142,7 @@ read_input_int :: (y: int, message: string) -> value: int, success: bool { input_pos_x := x + message.count + 2; input_width := size_x - input_pos_x; - str := read_input_string(input_pos_x, y, input_width); + str := read_input_string(input_pos_x, y, input_width,, temporary_allocator); value, success := parse_int(*str); return value, success; @@ -1170,7 +1174,6 @@ main :: () { defer free_memory(); { // Initialize app directory. - auto_release_temp(); home_dir, success_dir := get_home_directory(); // Returns system owned memory. if success_dir == false { home_dir = "."; @@ -1195,7 +1198,6 @@ main :: () { } { // Initialize database and archive files if needed. - auto_release_temp(); if (file_exists(db_file_path) == false) { if (store_database(database, db_file_path) == false) { print_error("Failed to initialize database."); @@ -1333,7 +1335,8 @@ main :: () { } if is_exit_requested { - exit(0); + // exit(0); // TODO fucking exit does not report memory leaks. + return; } } @@ -1353,7 +1356,9 @@ main :: () { TUI.flush_input(); TUI.set_next_key(TUI.Keys.Resize); while (true) { - + + reset_temporary_storage(); + TUI.set_style(style_default); if (is_terminal_too_small) { @@ -1366,7 +1371,6 @@ main :: () { draw_error_window(); } - reset_temporary_storage(); key := TUI.get_key(INPUT_TIMEOUT_MS); if key == #char "q" || key == #char "Q" break; update_times(*database); @@ -1456,7 +1460,7 @@ main :: () { // Change task name. TUI.using_style(action_style); - input := read_input_string(2, selected_task_row, Task.name.count, size_x - 2 - Task.name.count); + input := read_input_string(2, selected_task_row, Task.name.count, size_x - 2 - Task.name.count,, temporary_allocator); if is_empty_string(input) == false { replace_chars(input, "\t\x0B\x0C\r", #char " "); // Replace weird spaces with space. memset(selected_task.name.data, 0, Task.name.count); @@ -1492,9 +1496,9 @@ main :: () { case #char "6"; #through; case #char "7"; if (selected_task == null) continue; - + // Prepare position to input time operation. - selected_day := cast(int)(key - #char "1"); // TODO DAM this cast... + selected_day := cast(int)(key - #char "1"); input_width := layout.columns[L_DAYS_IDX + selected_day].width; input_pos_x := 2 + layout.columns[L_TITLE_IDX].width; for 0..selected_day-1 { @@ -1504,7 +1508,7 @@ main :: () { // Get input string. TUI.using_style(action_style); - input := read_input_string(input_pos_x, selected_task_row, input_width); // TODO Temp stringzes. + input := read_input_string(input_pos_x, selected_task_row, input_width,, temporary_allocator); // Abort if input if empty. if is_empty_string(input) continue; -- cgit v1.2.3