diff options
Diffstat (limited to 'main.c')
| -rw-r--r-- | main.c | 185 |
1 files changed, 105 insertions, 80 deletions
@@ -24,8 +24,8 @@ #define LOG_FILE_NAME "log.txt" #define APP_FOLDER_NAME ".task_time_tracker" -#define DB_BIN_PATH_NAME APP_FOLDER_NAME "/database.bin" -#define AR_CSV_PATH_NAME APP_FOLDER_NAME "/archive.csv" +#define DB_FILE_NAME "database.bin" +#define AR_FILE_NAME "archive.csv" typedef struct { int64_t times[NUM_WEEK_DAYS]; @@ -45,24 +45,30 @@ typedef struct { #define DB_FILE_SIGN_STR "TTT:B:01" const char DB_FILE_SIGN[] = DB_FILE_SIGN_STR; const size_t DB_FILE_SIGN_LENGTH = sizeof(DB_FILE_SIGN_STR)-1; -const size_t SIZEOF_TASK_T = sizeof(task_st); -const size_t SIZEOF_DATABASE_T = sizeof(database_st); +const size_t SIZEOF_TASK_ST = sizeof(task_st); +const size_t SIZEOF_DATABASE_ST = sizeof(database_st); const int64_t SECONDS_IN_MINUTE = (int64_t)60; const int64_t SECONDS_IN_HOUR = (int64_t)60*SECONDS_IN_MINUTE; const int64_t SECONDS_IN_DAY = (int64_t)24*SECONDS_IN_HOUR; const int64_t SECONDS_IN_YEAR = (int64_t)365*SECONDS_IN_DAY; -database_st database = { .tasks = NULL }; +database_st database = { .tasks = NULL }; database_st archive = { .tasks = NULL }; database_st *db = NULL; +// char *app_folder = NULL; +// char *db_file_path = NULL; +// char *ar_file_path = NULL; char *string_buffer = NULL; int size_x, size_y, pos_x, pos_y; +char *app_folder = NULL; +char *db_file_path = NULL; +char *ar_file_path = NULL; // Checks if file is exists and is accessible. // Returns true when the file exists and is accessible. -bool is_file_accessible(const char *path_name) { - assert(path_name != NULL); - FILE *file = fopen(path_name, "r+"); +bool is_file_accessible(const char *path) { + assert(path != NULL); + FILE *file = fopen(path, "r+"); bool is_file_accessible = file != NULL; if (is_file_accessible) { fclose(file); @@ -234,7 +240,7 @@ bool create_task(database_st *db, task_st **task) { current_capacity > PTRDIFF_MAX >> 1 ? PTRDIFF_MAX : current_capacity << 1; - task_st *new_tasks = realloc(db->tasks, new_capacity * SIZEOF_TASK_T); + task_st *new_tasks = realloc(db->tasks, new_capacity * SIZEOF_TASK_ST); if (new_tasks == NULL) { fprintf(stderr, "Failed to expand database.\n"); return false; @@ -246,7 +252,7 @@ bool create_task(database_st *db, task_st **task) { // Prepare new task. *task = &db->tasks[db->count]; - memset(*task, 0, SIZEOF_TASK_T); + memset(*task, 0, SIZEOF_TASK_ST); db->count++; @@ -269,7 +275,7 @@ bool add_task(database_st *db, task_st *task) { return false; } - memcpy(new_task, task, SIZEOF_TASK_T); + memcpy(new_task, task, SIZEOF_TASK_ST); // Add task timer values to total timers. for (int idx = 0; idx < NUM_WEEK_DAYS; idx++) { @@ -295,7 +301,7 @@ bool delete_task(database_st *db, task_st *task) { // Move tasks after the index position to their new positions. ptrdiff_t index = task - db->tasks; - memmove(task, task + 1, (db->count - index - 1) * SIZEOF_TASK_T); + memmove(task, task + 1, (db->count - index - 1) * SIZEOF_TASK_ST); db->count--; // Adjust selected task. @@ -315,7 +321,7 @@ bool delete_task(database_st *db, task_st *task) { size_t current_capacity = db->capacity; if (db->count <= (current_capacity >> 2)) { size_t new_capacity = current_capacity >> 1; - task_st *new_tasks = realloc(db->tasks, new_capacity * SIZEOF_TASK_T); + task_st *new_tasks = realloc(db->tasks, new_capacity * SIZEOF_TASK_ST); if (new_tasks == NULL && new_capacity > 0) { fprintf(stderr, "Failed to shrink database.\n"); return false; @@ -330,28 +336,28 @@ bool delete_task(database_st *db, task_st *task) { // Resets database to the initial state and deallocates all memory taken by tasks. void reset_database(database_st *db) { free(db->tasks); - memset(db, 0, SIZEOF_DATABASE_T); + memset(db, 0, SIZEOF_DATABASE_ST); db->active_task = -1; db->selected_task = -1; } // Stores data from database into binary file. // Returns success. -bool store_database(const database_st *db, const char *path_name) { +bool store_database(const database_st *db, const char *path) { assert(db != NULL); - assert(path_name != NULL); + assert(path != NULL); // Open file. - FILE *file = fopen(path_name, "wb"); + FILE *file = fopen(path, "wb"); if (file == NULL) { - fprintf(stderr, "Failed to open file '%s' while storing database: %s.\n", path_name, strerror(errno)); + fprintf(stderr, "Failed to open file '%s' while storing database: %s.\n", path, strerror(errno)); return false; } fwrite(DB_FILE_SIGN, sizeof(char), DB_FILE_SIGN_LENGTH, file); - fwrite(db, SIZEOF_DATABASE_T, 1, file); - fwrite(db->tasks, SIZEOF_TASK_T, db->count, file); + fwrite(db, SIZEOF_DATABASE_ST, 1, file); + fwrite(db->tasks, SIZEOF_TASK_ST, db->count, file); fclose(file); return true; @@ -359,15 +365,15 @@ bool store_database(const database_st *db, const char *path_name) { // Loads data from binary file into database. // Returns success. -bool load_database(database_st *db, const char *path_name) { +bool load_database(database_st *db, const char *path) { assert(db != NULL); - assert(path_name != NULL); + assert(path != NULL); // Open file. - FILE *file = fopen(path_name, "rb"); + FILE *file = fopen(path, "rb"); if (file == NULL) { - fprintf(stderr, "Failed to open file '%s' while loading database: %s.\n", path_name, strerror(errno)); + fprintf(stderr, "Failed to open file '%s' while loading database: %s.\n", path, strerror(errno)); return false; } @@ -380,13 +386,13 @@ bool load_database(database_st *db, const char *path_name) { } // Read database structure. - fread(db, SIZEOF_DATABASE_T, 1, file); + fread(db, SIZEOF_DATABASE_ST, 1, file); // Restore database capacity. - db->tasks = calloc(db->capacity, SIZEOF_TASK_T); + db->tasks = calloc(db->capacity, SIZEOF_TASK_ST); // Read database entries. - fread(db->tasks, SIZEOF_TASK_T, db->count, file); + fread(db->tasks, SIZEOF_TASK_ST, db->count, file); // Make sure we are reading all the file. assert(fgetc(file) == EOF); @@ -397,14 +403,14 @@ bool load_database(database_st *db, const char *path_name) { // Exports data into CSV file. // Returns success. -bool export_to_csv(const database_st *db, const char *path_name) { +bool export_to_csv(const database_st *db, const char *path) { assert(db != NULL); - assert(path_name != NULL); + assert(path != NULL); - FILE *file = fopen(path_name, "w"); + FILE *file = fopen(path, "w"); if (file == NULL) { - fprintf(stderr, "Failed to open file '%s' while exporting to CSV: %s.\n", path_name, strerror(errno)); + fprintf(stderr, "Failed to open file '%s' while exporting to CSV: %s.\n", path, strerror(errno)); return false; } @@ -442,13 +448,13 @@ bool export_to_csv(const database_st *db, const char *path_name) { // Imports CSV file into database. // Returns success. -bool import_from_csv(database_st *db, const char *path_name) { +bool import_from_csv(database_st *db, const char *path) { assert(db != NULL); - assert(path_name != NULL); + assert(path != NULL); - FILE *file = fopen(path_name, "r"); + FILE *file = fopen(path, "r"); if (file == NULL) { - fprintf(stderr, "Failed to open file '%s' while importing from CSV: %s.\n", path_name, strerror(errno)); + fprintf(stderr, "Failed to open file '%s' while importing from CSV: %s.\n", path, strerror(errno)); return false; } @@ -508,13 +514,13 @@ bool import_from_csv(database_st *db, const char *path_name) { return true; } -bool append_to_csv(task_st *task, const char *path_name) { +bool append_to_csv(task_st *task, const char *path) { assert(task != NULL); - assert(path_name != NULL); + assert(path != NULL); - FILE *file = fopen(path_name, "a+"); + FILE *file = fopen(path, "a+"); if (file == NULL) { - fprintf(stderr, "Failed to open file '%s' while appending to CSV: %s.\n", path_name, strerror(errno)); + fprintf(stderr, "Failed to open file '%s' while appending to CSV: %s.\n", path, strerror(errno)); return false; } @@ -627,15 +633,15 @@ void update_total_timers(database_st *db) { typedef struct { - char *header; - int width; - char alignment; - int alignment_offset; + char *header; + int width; + char alignment; + int alignment_offset; } column_st; typedef struct { - column_st columns[NUM_COLUMNS]; - char *archive_title; + column_st columns[NUM_COLUMNS]; + char *archive_title; } layout_st; layout_st layouts[2]; @@ -899,39 +905,58 @@ void draw_tui(database_st *db, layout_st *layout) { mvaddstr(y, x, string_buffer); } -char *app_folder = NULL; - void free_memory() { reset_database(&database); reset_database(&archive); - free(string_buffer); - string_buffer = NULL; - - free(app_folder); - app_folder = NULL; + free(string_buffer); string_buffer = NULL; + free(app_folder); app_folder = NULL; + free(db_file_path); db_file_path = NULL; + free(ar_file_path); ar_file_path = NULL; } -bool initialize_app_folder(const char *path) { - size_t path_length = strlen(path); - size_t app_folder_name_length = strlen(APP_FOLDER_NAME); - app_folder = malloc(path_length + app_folder_name_length + 2 + 1); // Add 2 for the '/'s and 1 for the NUL. - memcpy(app_folder, path, path_length); - app_folder[path_length] = '/'; - memcpy(app_folder + path_length + 1, APP_FOLDER_NAME, app_folder_name_length); - app_folder[path_length + 1 + app_folder_name_length] = '/'; - - mkdir(app_folder, 0740); - if (errno != 0 && errno != EEXIST) { - fprintf(stderr, "Failed to create app folder '%s': %s.\n", app_folder, strerror(errno)); - return false; +bool initialize_app_folder() { + char* home_path = getenv("HOME"); + +#if defined(_WIN64) + home_path = getenv("USERPROFILE"); +#endif + + if (home_path != NULL) + { + app_folder = malloc(strlen(home_path) + 1 + strlen(APP_FOLDER_NAME) + 1); // Add space for folder separator and NUL. + // TODO Check malloc result. + sprintf(app_folder, "%s/%s", home_path, APP_FOLDER_NAME); + + // Create app folder. + mkdir(app_folder, 0740); + if (errno != 0 && errno != EEXIST) { + fprintf(stderr, "Failed to create app folder '%s': %s.\n", app_folder, strerror(errno)); + return false; + } } + else { + app_folder = malloc(3); + // TODO Check malloc result. + sprintf(app_folder, "./"); + } + + // Set database file path. + db_file_path = malloc(strlen(app_folder) + 1 + strlen(DB_FILE_NAME) + 1); // Add space for folder separator and NUL. + // TODO Check malloc result. + sprintf(db_file_path, "%s/%s", app_folder, DB_FILE_NAME); + + // Set archive file path. + ar_file_path = malloc(strlen(app_folder) + 1 + strlen(AR_FILE_NAME) + 1); // Add space for folder separator and NUL. + // TODO Check malloc result. + sprintf(ar_file_path, "%s/%s", app_folder, AR_FILE_NAME); + return true; } int main(int argc, char *argv[]) { - if (initialize_app_folder(getenv("HOME")) == false) { + if (initialize_app_folder() == false) { return EXIT_FAILURE; } @@ -939,12 +964,12 @@ int main(int argc, char *argv[]) { reset_database(&database); reset_database(&archive); - if (is_file_accessible(DB_BIN_PATH_NAME) == false) { - store_database(&database, DB_BIN_PATH_NAME); + if (is_file_accessible(db_file_path) == false) { + store_database(&database, db_file_path); } - if (is_file_accessible(AR_CSV_PATH_NAME) == false) { - export_to_csv(&archive, AR_CSV_PATH_NAME); + if (is_file_accessible(ar_file_path) == false) { + export_to_csv(&archive, ar_file_path); } if (argc > 1) { @@ -974,9 +999,9 @@ int main(int argc, char *argv[]) { if (argc < idx+1) { fprintf(stdout, "Missing CSV file path to import.\n"); } - load_database(&database, DB_BIN_PATH_NAME); + load_database(&database, db_file_path); import_from_csv(&database, argv[idx+1]); - store_database(&database, DB_BIN_PATH_NAME); + store_database(&database, db_file_path); free_memory(); return EXIT_SUCCESS; } @@ -987,7 +1012,7 @@ int main(int argc, char *argv[]) { if (argc < idx+1) { fprintf(stdout, "Missing CSV file path to export.\n"); } - load_database(&database, DB_BIN_PATH_NAME); + load_database(&database, db_file_path); export_to_csv(&database, argv[idx+1]); free_memory(); return EXIT_SUCCESS; @@ -1000,7 +1025,7 @@ int main(int argc, char *argv[]) { initialize_tui(); - load_database(&database, DB_BIN_PATH_NAME); + load_database(&database, db_file_path); ungetch(KEY_RESIZE); for (int key; (key = getch()) != 'q'; ) { @@ -1101,18 +1126,18 @@ int main(int argc, char *argv[]) { db->active_task = next_task - db->tasks; } db->modified_on = time(NULL); - store_database(db, DB_BIN_PATH_NAME); + store_database(db, db_file_path); break; } case KEY_BACKSPACE: if (db == &database) { reset_database(&archive); // TODO Not needed because we never leave things hanging. - import_from_csv(&archive, AR_CSV_PATH_NAME); + import_from_csv(&archive, ar_file_path); db = &archive; } else { - export_to_csv(&archive, AR_CSV_PATH_NAME); + export_to_csv(&archive, ar_file_path); reset_database(&archive); db = &database; } @@ -1123,7 +1148,7 @@ int main(int argc, char *argv[]) { if (db != &database || selected_task == NULL || selected_task == active_task) { break; } - append_to_csv(selected_task, AR_CSV_PATH_NAME); + append_to_csv(selected_task, ar_file_path); delete_task(db, selected_task); // TODO Maybe save stuff? Shoulw we? break; @@ -1195,9 +1220,9 @@ int main(int argc, char *argv[]) { } update_timers(&database); - store_database(&database, DB_BIN_PATH_NAME); + store_database(&database, db_file_path); if (db == &archive) { - export_to_csv(&archive, AR_CSV_PATH_NAME); + export_to_csv(&archive, ar_file_path); } free_memory(); endwin(); |
