aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.c107
1 files 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;
}