From 145f222bebc0cd04e5bf7462563216780e13558b Mon Sep 17 00:00:00 2001 From: Unbewohnte Date: Sun, 20 Aug 2023 21:24:44 +0300 Subject: [PATCH] feat: show-done and done commands --- README.md | 2 +- src/main.c | 45 +++++++++++++++++++++++++++++---------- src/todo.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++------ src/todo.h | 23 +++++++++++++++++--- 4 files changed, 110 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 850e230..fb44fcf 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ Commands: - `add [todo]... -> Writes a new TODO to a default TODO file` - `show -> Outputs current TODOs` - `show-done -> Outputs TODOs which were done previously` -- `done [index OR index1-index2 OR index1,index2] -> Marks specified TODO(s) as done` +- `done [index]... -> Marks specified TODO(s) as done` ## License diff --git a/src/main.c b/src/main.c index 7e61987..e92c785 100644 --- a/src/main.c +++ b/src/main.c @@ -90,7 +90,7 @@ int main(int argc, char** argv) { // Collect and work out arguments - while (i < argc) { + while (i+1 < argc) { i++; arg = argv[i]; @@ -104,7 +104,7 @@ int main(int argc, char** argv) { \nadd [todo] -> Writes a new TODO to a default TODO file\ \nshow -> Outputs current TODOs\ \nshow-done -> Outputs TODOs which were done previously\ - \ndone [index OR index1-index2 OR index1,index2] -> Marks specified TODO(s) as done\ + \ndone [index]... -> Marks specified TODO(s) as done\ \n" ); clean_up(todo_file, todos, todo_count, todo_file_path); @@ -138,7 +138,7 @@ int main(int argc, char** argv) { } Todo* new_todo = todo_new(strlen(todo_text), todo_text); - if (todo_write(todo_file, new_todo) == EXIT_FAILURE) { + if (todo_write_end(todo_file, new_todo) == EXIT_FAILURE) { fprintf(stderr, "[ERR] Failed to write a new todo: %s\n", strerror(errno)); clean_up(todo_file, todos, todo_count, todo_file_path); return EXIT_FAILURE; @@ -159,11 +159,17 @@ int main(int argc, char** argv) { return EXIT_SUCCESS; } + size_t printed = 0; for (size_t j = 0; j < todo_count; j++) { if (todos[j]->done) { continue; } printf("[%ld] %s\n", j, todos[j]->text); + printed++; + } + + if (printed == 0) { + printf("All is done!\n"); } clean_up(todo_file, todos, todo_count, todo_file_path); @@ -197,7 +203,7 @@ int main(int argc, char** argv) { } - // Done command TODO!!!!! + // Done command if (strcmp(arg, "done") == 0) { int result = todos_read(todo_file, &todos, &todo_count); if (result == EXIT_FAILURE && todo_count == 0) { @@ -207,20 +213,37 @@ int main(int argc, char** argv) { i++; if (i >= argc) { - // Not one index was specified - // Mark the first one as DONE - + printf("Not one index was specified!\n"); + clean_up(todo_file, todos, todo_count, todo_file_path); + return EXIT_SUCCESS; } - arg = argv[i]; - - + for (size_t j = 0; j < todo_count; j++) { if (todos[j]->done) { continue; } - printf("[%ld] %s\n", j, todos[j]->text); + + for (size_t arg_index = i; arg_index < argc; arg_index++) { + size_t index = (size_t) atoll(argv[arg_index]); + if (index >= todo_count) { + continue; + } + + if (j == index) { + // Mark as done + todo_mark_done(todos[j]); + printf("Marked \" %s\" as done!\n", todos[j]->text); + } + } } + // Re-write TODO file (Truncation is no needed as only one bit has changed) + fseek(todo_file, 0, SEEK_SET); + if (todos_write(todo_file, todos, todo_count) == EXIT_FAILURE) { + fprintf(stderr, "[ERR] Failed to write updated todos to a todo file: %s\n", strerror(errno)); + clean_up(todo_file, todos, todo_count, todo_file_path); + return EXIT_FAILURE; + } clean_up(todo_file, todos, todo_count, todo_file_path); return EXIT_SUCCESS; diff --git a/src/todo.c b/src/todo.c index 53c7b01..73a31fc 100644 --- a/src/todo.c +++ b/src/todo.c @@ -72,7 +72,7 @@ void todo_delete(Todo** todo) { /* -Writes a provided todo to a file at current position in binary representation. +Writes a provided todo to a file at the current position in binary representation. Returns EXIT_FAILURE if an error has occured. */ @@ -82,9 +82,6 @@ int todo_write(FILE* file, const Todo* todo) { if (!file) { return EXIT_FAILURE; } - - // Append to the end of the file - fseek(file, 0, SEEK_END); // Text length items_written = fwrite(&todo->text_len, sizeof(uint32_t), 1, file); @@ -108,6 +105,50 @@ int todo_write(FILE* file, const Todo* todo) { } +/* +Writes a provided todo to a file at the end of the file in binary representation. + +Returns EXIT_FAILURE if an error has occured. +*/ +int todo_write_end(FILE* file, const Todo* todo) { + if (!file) { + return EXIT_FAILURE; + } + + // Append to the end of the file + fseek(file, 0, SEEK_END); + + return todo_write(file, todo); +} + + +/* +Writes given TODOs to file. File cursor isn't changed in any way. + +Returns EXIT_FAILURE in case of an error. +*/ +int todos_write(FILE* file, Todo** todos, size_t todo_count) { + if (!file || !todos) { + return EXIT_FAILURE; + } + if (!(*todos)) { + return EXIT_FAILURE; + } + + for (size_t i = 0; i < todo_count; i++) { + if (!todos[i]) { + continue; + } + + if (todo_write(file, todos[i]) == EXIT_FAILURE) { + return EXIT_FAILURE; + } + } + + return EXIT_SUCCESS; +} + + /* Reads the next TODO in provided file, puts it in todo. @@ -182,7 +223,14 @@ int todos_read(FILE* file, Todo*** todos, size_t* todos_read) { } -//TODO -int todo_mark_done() { - return EXIT_SUCCESS; +/* +Marks todo as done +*/ +void todo_mark_done(Todo* todo) { + if (!todo) { + return; + } + + todo->done = 1; + return; } \ No newline at end of file diff --git a/src/todo.h b/src/todo.h index 99a4f0c..6c16e24 100644 --- a/src/todo.h +++ b/src/todo.h @@ -39,13 +39,28 @@ void todo_delete(Todo** todo); /* -Writes a provided todo to a file at current position in binary representation. +Writes a provided todo to a file at the current position in binary representation. Returns EXIT_FAILURE if an error has occured. */ int todo_write(FILE* file, const Todo* todo); +/* +Writes a provided todo to a file at the end of the file in binary representation. + +Returns EXIT_FAILURE if an error has occured. +*/ +int todo_write_end(FILE* file, const Todo* todo); + + +/* +Writes given TODOs to file. File cursor isn't changed in any way. + +Returns EXIT_FAILURE in case of an error. +*/ +int todos_write(FILE* file, Todo** todos, size_t todo_count); + /* Reads the next TODO in provided file, puts it in todo. @@ -66,5 +81,7 @@ Returns EXIT_FAILURE if an error occured somewhere. int todos_read(FILE* file, Todo*** todos, size_t* todos_read); -//TODO -int todo_mark_done(); \ No newline at end of file +/* +Marks todo as done +*/ +void todo_mark_done(Todo* todo); \ No newline at end of file