From 627f0f4cf3cbe1c983d1fd240298411cba84352f Mon Sep 17 00:00:00 2001 From: dam Date: Wed, 14 Dec 2022 01:51:46 +0000 Subject: Fixed bug on duplicate_task. Fixed some to-do entries. --- main.c | 107 ++++++++++++++++++++++++++++++----------------------------------- 1 file changed, 49 insertions(+), 58 deletions(-) diff --git a/main.c b/main.c index 1b7e4da..2557afe 100644 --- a/main.c +++ b/main.c @@ -121,14 +121,12 @@ bool is_equal_to_any(const char *to_compare, const char *test_a, const char *tes size_t truncate_string_utf8(char *string, size_t length) { assert(string != NULL); - // TODO Review this function... - - // Count continuation bytes. + // Find index of first continuation byte. size_t idx = length; while (idx > 0 && ((string[idx - 1] & 0xC0) == 0x80)) { idx--; } - int continuation_bytes = length - idx; + size_t continuation_bytes = length - idx; // If string starts with continuation bytes, it's an invalid UTF8 string. if (idx == 0 && continuation_bytes > 0) { @@ -142,48 +140,13 @@ size_t truncate_string_utf8(char *string, size_t length) { && !(continuation_bytes == 2 && (string[idx - 1] & 0xF0) == 0xE0) && !(continuation_bytes == 3 && (string[idx - 1] & 0xF8) == 0xF0) ) { - length -= (continuation_bytes + 1); + length -= (continuation_bytes + 1); // Remove '+ 1' start byte. } string[length] = '\0'; return length; } -// TODO Used to test the truncate_string_utf8 -void test_truncate_string_utf8() { - char t_a[] = { (char)0x61, (char)0x3A, (char)0xC3, (char)0xB3, 'a', 0 }; - char t_b[] = { (char)0xC3, (char)0xB3, 0 }; - char t_c[] = { (char)0xB3, 0 }; - char t[1024]; - - fprintf(stderr, "a --- --- ---\n"); - for (int l = 5; l >= 0; l--) { - memset(t, 0, 1024); - memcpy(t, t_a, 6); - fprintf(stderr, "%d : '%s'", l , t); - truncate_string_utf8(t, l); - fprintf(stderr, " '%s'\n", t); - } - - fprintf(stderr, "b --- --- ---\n"); - for (int l = 2; l >= 0; l--) { - memset(t, 0, 1024); - memcpy(t, t_b, 3); - fprintf(stderr, "%d : '%s'", l , t); - truncate_string_utf8(t, l); - fprintf(stderr, " '%s'\n", t); - } - - fprintf(stderr, "c --- --- ---\n"); - for (int l = 1; l >= 0; l--) { - memset(t, 0, 1024); - memcpy(t, t_c, 2); - fprintf(stderr, "%d : '%s'", l , t); - truncate_string_utf8(t, l); - fprintf(stderr, " '%s'\n", t); - } -} - // Returns true when the string is empty or consists of white space characters. bool is_empty_string(char *string) { for (int idx = 0; string[idx] != '\0'; idx++) { @@ -364,11 +327,18 @@ bool duplicate_task(database_st *db, task_st *task) { assert(db != NULL); assert(task != NULL); + // Create new task and keep task_idx (relative pointer) of original task). + ptrdiff_t task_idx = task - db->tasks; task_st *new_task; if (create_task(db, &new_task) == false) { return false; } + // If original task belonged to database, fix its pointer. + if (0 <= task_idx && task_idx < db->count - 1) { // Compensate '- 1' for the new task. + task = db->tasks + task_idx; + } + memcpy(new_task, task, SIZEOF_TASK_ST); // Add task time values to total times. @@ -1174,6 +1144,7 @@ void read_input_to_string_buffer(int row, int column, int length) { int main(int argc, char *argv[]) { if (initialize_app_folder() == false) { + free_memory(); return EXIT_FAILURE; } @@ -1182,11 +1153,17 @@ int main(int argc, char *argv[]) { reset_database(&archive); if (is_file_accessible(db_file_path) == false) { - store_database(&database, db_file_path); // TODO Check for error. + if (store_database(&database, db_file_path) == false) { + free_memory(); + return EXIT_FAILURE; + } } if (is_file_accessible(ar_file_path) == false) { - export_to_csv(&archive, ar_file_path); // TODO Check for error. + if (export_to_csv(&archive, ar_file_path) == false) { + free_memory(); + return EXIT_FAILURE; + } } if (argc > 1) { @@ -1205,7 +1182,7 @@ int main(int argc, char *argv[]) { "In app commands\n" " a, A Archive selected task (except if active).\n" " u, U Unarchive selected task.\n" - " c, C Select currently active task.\n" + " c, C Select currently active task (if any).\n" " d, D Duplicate selected task.\n" " n, N Create new task.\n" " m, M Move selected task to position.\n" @@ -1232,10 +1209,10 @@ int main(int argc, char *argv[]) { " END Select last/bottom task.\n" "\n" "Notes\n" - " During intensive tasks such as, saving to file or recalculating totals times,\n" - " a diamond simbol is shown on the top left corner. This should only be visible\n" - " on databases with more than 1000000 tasks.\n" + " During intensive tasks such as saving to file or recalculating totals times,\n" + " a diamond symbol is shown on the top left corner.\n" ); + free_memory(); return EXIT_SUCCESS; } @@ -1252,10 +1229,18 @@ int main(int argc, char *argv[]) { free_memory(); return EXIT_FAILURE; } - // TODO No error checking... oh noes! - load_database(&database, db_file_path); - import_from_csv(&database, argv[idx]); - store_database(&database, db_file_path); + if (load_database(&database, db_file_path) == false) { + free_memory(); + return EXIT_FAILURE; + } + if (import_from_csv(&database, argv[idx]) == false) { + free_memory(); + return EXIT_FAILURE; + } + if (store_database(&database, db_file_path) == false) { + free_memory(); + return EXIT_FAILURE; + } reset_database(&database); is_exit_requested = true; continue; @@ -1268,9 +1253,14 @@ int main(int argc, char *argv[]) { free_memory(); return EXIT_FAILURE; } - // TODO No error checking... oh noes! - load_database(&database, db_file_path); - export_to_csv(&database, argv[idx]); + if (load_database(&database, db_file_path) == false) { + free_memory(); + return EXIT_FAILURE; + } + if (export_to_csv(&database, argv[idx]) == false) { + free_memory(); + return EXIT_FAILURE; + } reset_database(&database); is_exit_requested = true; continue; @@ -1282,10 +1272,12 @@ int main(int argc, char *argv[]) { } fprintf(stdout, "%s: invalid option '%s'.\nTry '%s --help' for more information.\n", argv[0], argv[idx], argv[0]); + free_memory(); return EXIT_FAILURE; } if (is_exit_requested) { + free_memory(); return EXIT_SUCCESS; } } @@ -1446,7 +1438,7 @@ int main(int argc, char *argv[]) { // TODO Check if parsed OK. For that, I need to read the manual to know what strtoX returns. // TODO It seems that the float parsing may return INF or NAN. Take special care with those. - // TODO Once I know the parse was OK, I'll check the remaining of the string for multiplies: + // TODO Once I know the parse was OK, I'll check the remaining of the string for multipliers: // s/S - second (default if none is found) // m/M - minute // h/H - hour @@ -1662,7 +1654,7 @@ int main(int argc, char *argv[]) { break; } append_to_csv(selected_task, ar_file_path); - delete_task(db, selected_task); + delete_task(&database, selected_task); trigger_autosave(); break; } @@ -1673,7 +1665,7 @@ int main(int argc, char *argv[]) { break; } duplicate_task(&database, selected_task); - delete_task(db, selected_task); + delete_task(&archive, selected_task); trigger_autosave(); break; } @@ -1730,8 +1722,7 @@ int main(int argc, char *argv[]) { store_database(&database, db_file_path); } - free_memory(); endwin(); - + free_memory(); return EXIT_SUCCESS; } -- cgit v1.2.3