aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--task_tracker.c273
1 files changed, 227 insertions, 46 deletions
diff --git a/task_tracker.c b/task_tracker.c
index 9901d22..cb41edc 100644
--- a/task_tracker.c
+++ b/task_tracker.c
@@ -8,6 +8,15 @@
#include <string.h>
#include <time.h>
+#define STR_(X) #X // Convert to string.
+#define STR(X) STR_(X) // Force argument expansions before converting to string.
+
+#define MAX_TASK_NAME 127
+#define INITIAL_DAY_OF_WEEK 1 // (0-6, Sunday = 0)
+
+#define LOG_FILE_NAME "log.txt"
+#define DB_FILE_NAME "database.bin"
+
struct task_event {
char* name;
@@ -15,15 +24,18 @@ struct task_event {
time_t end;
};
-#define MAX_TASK_NAME 196 // (256-4-7*8)
-
struct task_info {
uint32_t hash;
- uint64_t time[7];
- char name[MAX_TASK_NAME];
+ uint32_t time[7];
+ char name[MAX_TASK_NAME+1]; // Allow space for null termination char.
};
+const char* DB_FILE_SIGNATURE = "TTBF:1.0";
+const uint8_t FILE_SIGNATURE_SIZE = sizeof(DB_FILE_SIGNATURE);
+const size_t TASK_INFO_SIZE = sizeof(struct task_info);
+
+
struct task_info* tasks = NULL;
uint32_t tasks_count = 0;
uint32_t tasks_capacity = 0;
@@ -34,6 +46,66 @@ uint32_t tasks_names_size = 0;
uint32_t tasks_names_capacity = 0;
+void print_task(const struct task_info* task) {
+ printf("name: '%s'\n", task->name);
+ printf("hash: '%" PRIu32 "'\n", task->hash);
+ printf("t[0]: '%" PRIu32 "'\n", task->time[0]);
+ printf("t[1]: '%" PRIu32 "'\n", task->time[1]);
+ printf("t[2]: '%" PRIu32 "'\n", task->time[2]);
+ printf("t[3]: '%" PRIu32 "'\n", task->time[3]);
+ printf("t[4]: '%" PRIu32 "'\n", task->time[4]);
+ printf("t[5]: '%" PRIu32 "'\n", task->time[5]);
+ printf("t[6]: '%" PRIu32 "'\n", task->time[6]);
+}
+
+void store_database(const struct task_info* database, uint32_t number_of_entries) {
+
+ const char* DB_FILE_SIGNATURE = "TTBF:1.0";
+ const uint8_t FILE_SIGNATURE_SIZE = sizeof(DB_FILE_SIGNATURE);
+ const size_t TASK_INFO_SIZE = sizeof(struct task_info);
+
+ FILE* file = fopen("./" DB_FILE_NAME, "w");
+
+ fwrite(DB_FILE_SIGNATURE, sizeof(char), FILE_SIGNATURE_SIZE, file);
+ fwrite(&number_of_entries, sizeof(number_of_entries), 1, file);
+ fwrite(database, TASK_INFO_SIZE, number_of_entries, file);
+
+ fclose(file);
+}
+
+uint32_t load_database(struct task_info** database) {
+
+ const char* DB_FILE_SIGNATURE = "TTBF:1.0";
+ const uint8_t FILE_SIGNATURE_SIZE = sizeof(DB_FILE_SIGNATURE);
+ const size_t TASK_INFO_SIZE = sizeof(struct task_info);
+
+ FILE* file = fopen("./" DB_FILE_NAME, "r");
+
+ char file_signature[FILE_SIGNATURE_SIZE];
+ fread(&file_signature, sizeof(char), FILE_SIGNATURE_SIZE, file);
+ if (strncmp(file_signature, DB_FILE_SIGNATURE, FILE_SIGNATURE_SIZE) != 0) {
+ printf("Invalid file signature.\n");
+ return 0;
+ }
+
+ fprintf(stderr, "-4\n");
+ uint32_t number_of_entries;
+ fread(&number_of_entries, sizeof(number_of_entries), 1, file);
+ fprintf(stderr, "number of entries: %" PRIu32 "\n", number_of_entries);
+
+ fprintf(stderr, "pointer_value: %p : *%p\n", database, *database);
+ *database = calloc(number_of_entries, TASK_INFO_SIZE);
+ fprintf(stderr, "pointer_value: %p : *%p\n", database, *database);
+
+ fread(*database, TASK_INFO_SIZE, number_of_entries, file);
+
+ fclose(file);
+
+ print_task(*database);
+
+ return number_of_entries;
+}
+
uint32_t CRC32(const uint8_t data[], size_t data_length) {
static const uint32_t crc32_table[] = {
@@ -94,8 +166,14 @@ uint32_t CRC32(const uint8_t data[], size_t data_length) {
return crc32;
}
-void add_task(char* name)
-{
+uint32_t hash_string(const char* string) {
+ size_t data_length = strlen(string);
+ uint8_t* data = (uint8_t*)string;
+ return CRC32(data, data_length);
+}
+
+void add_task(char* name) {
+
// Exit if task has already been added.
uint32_t name_hash = CRC32((uint8_t*)name, sizeof(name));
for (uint32_t idx = 0; idx < tasks_count; idx++)
@@ -116,20 +194,54 @@ void add_task(char* name)
// Add new task entry.
struct task_info* new_task = &tasks[tasks_count];
memset(new_task, '0', sizeof(struct task_info));
- strncpy(new_task->name, name, MAX_TASK_NAME); // TODO should we limit this here, on during sscanf? Maybe leave it in both.
- new_task->name[MAX_TASK_NAME-1] = '\0';
+ strncpy(new_task->name, name, MAX_TASK_NAME);
+ new_task->name[MAX_TASK_NAME] = '\0';
printf(">>> %s\n", new_task->name); // TODO debug
new_task->hash = name_hash;
tasks_count++;
}
-void add_task_event(char* name, uint64_t start, uint64_t end)
-{
+void add_task_event(char* name, uint64_t start, uint64_t end) {
// TODO Missing the task_event array.
}
-void fake_data()
-{
+void prototype() {
+
+ time_t now_ut = time(NULL);
+ uint8_t week_day = localtime(&now_ut)->tm_wday;
+ printf("=== Bazinga : %d\n", week_day);
+
+
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Test moving database data from memory to file and back to memory.
+
+ struct task_info task;
+ memset(&task, '0', TASK_INFO_SIZE);
+ strncpy(task.name, "TASK-00 : Sample task name.", MAX_TASK_NAME+1);
+ task.time[0] = 0;
+ task.time[1] = 10;
+ task.time[2] = 11;
+ task.time[3] = 12;
+ task.time[4] = 333;
+ task.time[5] = 555;
+ task.time[6] = 777;
+ task.hash = hash_string(task.name);
+ print_task(&task);
+ store_database(&task, 1);
+
+
+ struct task_info* task_dest = NULL;
+ uint32_t number_of_entries = load_database(&task_dest);
+
+ print_task(task_dest);
+ fprintf(stderr, ">>>>> %" PRIu32 "\n", number_of_entries);
+ free(task_dest);
+ ///////////////////////////////////////////////////////////////////////////
+
+ return;
+
+
const char* csv_head = "task_name,start,end";
const char* csv_line[] = {
"PI-0000,1659479138,1659482738",
@@ -164,11 +276,105 @@ void fake_data()
uint64_t end;
printf("--- --- àè.ªãº.éá --- ---\n");
+ //////////////////////////////////////////////////
+ // TODO Use this to parse the tasks names. TODO //
+ // TODO WIP TODO WIP TODO WIP TODO
+ const char* task_info_A = "Lorem ipsum dolor sit amet consectetur adipiscing elit sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Vel turpis nunc eget lorem. Non pulvinar neque laoreet suspendisse interdum consectetur libero id,165147,14790,9138,1,2,3,4";
+ const char* task_info_B = "Lorem,165147,14790,9138,1,2,3,4";
+
+#define COISA
+#define SPACER "%*[^,]"
+
+ const char* format = "%" STR(MAX_TASK_NAME) "[^,]" SPACER ",%" SCNu32 ",%" SCNu32 ",%" SCNu32 ",%" SCNu32 ",%" SCNu32 ",%" SCNu32 ",%" SCNu32;
+
+// struct task_info task_A;
+// sscanf(task_info_A, format,
+// task_A.name,
+// &task_A.time[0],
+// &task_A.time[1],
+// &task_A.time[2],
+// &task_A.time[3],
+// &task_A.time[4],
+// &task_A.time[5],
+// &task_A.time[6]
+// ); // TODO WIP
+
+ const char* format_X = "%" STR(MAX_TASK_NAME) "[^,]";
+
+ struct task_info task_A;
+ sscanf(task_info_A, format_X,
+ task_A.name
+ ); // TODO WIP
+
+ const char* format_Y = "%*[^,],%" SCNu32 ",%" SCNu32 ",%" SCNu32 ",%" SCNu32 ",%" SCNu32 ",%" SCNu32 ",%" SCNu32;
+
+ sscanf(task_info_A, format_Y,
+ &task_A.time[0],
+ &task_A.time[1],
+ &task_A.time[2],
+ &task_A.time[3],
+ &task_A.time[4],
+ &task_A.time[5],
+ &task_A.time[6]
+ ); // TODO WIP
+
+// struct task_info task_B;
+// sscanf(task_info_B,format,
+// task_B.name,
+// &task_B.time[0],
+// &task_B.time[1],
+// &task_B.time[2],
+// &task_B.time[3],
+// &task_B.time[4],
+// &task_B.time[5],
+// &task_B.time[6]
+// ); // TODO WIP
+
+ struct task_info task_B;
+ sscanf(task_info_B,format_X,
+ task_B.name
+ ); // TODO WIP
+
+ sscanf(task_info_B,format_Y,
+ &task_B.time[0],
+ &task_B.time[1],
+ &task_B.time[2],
+ &task_B.time[3],
+ &task_B.time[4],
+ &task_B.time[5],
+ &task_B.time[6]
+ ); // TODO WIP
+
+ printf("--------------------------------------------------\n");
+ printf("name: '%s'\n", task_A.name);
+ printf("t[0]: '%d'\n", task_A.time[0]);
+ printf("t[1]: '%d'\n", task_A.time[1]);
+ printf("t[2]: '%d'\n", task_A.time[2]);
+ printf("t[3]: '%d'\n", task_A.time[3]);
+ printf("t[4]: '%d'\n", task_A.time[4]);
+ printf("t[5]: '%d'\n", task_A.time[5]);
+ printf("t[6]: '%d'\n", task_A.time[6]);
+
+ printf("name: '%s'\n", task_B.name);
+ printf("t[0]: '%d'\n", task_B.time[0]);
+ printf("t[1]: '%d'\n", task_B.time[1]);
+ printf("t[2]: '%d'\n", task_B.time[2]);
+ printf("t[3]: '%d'\n", task_B.time[3]);
+ printf("t[4]: '%d'\n", task_B.time[4]);
+ printf("t[5]: '%d'\n", task_B.time[5]);
+ printf("t[6]: '%d'\n", task_B.time[6]);
+ printf("--------------------------------------------------\n");
+
+ ///////////////////////////////////////////////////////////////
+
uint32_t lines_count = sizeof(csv_line)/sizeof(char*);
for (uint32_t idx = 0; idx < lines_count; idx++)
{
// TODO The following sscanf is allocating memory for the name... we should remove it.
- sscanf(csv_line[idx], "%m[^,\n],%" SCNu64 ",%" SCNu64, &name, &start, &end); // TODO WIP
+// uint32_t max_task_name
+
+ // TODO The m modifier requires us to free the memory returned.
+ sscanf(csv_line[idx], "%" STR(MAX_TASK_NAME) "m[^,\n],%" SCNu64 ",%" SCNu64, &name, &start, &end); // TODO WIP
add_task(name);
// printf("bazinga: %s : %d : %d\n", name, start, end);
// printf("bazinga: %s : %.19s : %.19s\n", name, ctime(&start), ctime(&end));
@@ -177,8 +383,6 @@ void fake_data()
printf("### ### --------- ### ###\n");
-
-
// tasks_names =
@@ -191,18 +395,6 @@ void fake_data()
free(tasks_names);
return;
- /*
- char *token, *copy, *to_free;
- copy = to_free = strdup(csv_line);
-
-
- while ( token = strsep(&str, ",") )
- {
- my_fn(token);
- }
- free(to_free);
- */
-
// tasks_names = malloc( ...
@@ -224,14 +416,11 @@ void fake_data()
}
-void draw_table()
-{
+void draw_table() {
struct task_info asd;
}
-
-void draw_header()
-{
+void draw_header() {
const char *table_headers[] = { "Task", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun", "Total" };
const int table_headers_size = sizeof(table_headers)/sizeof(char*);
@@ -259,8 +448,7 @@ void draw_header()
addch(ACS_URCORNER);
}
-void draw_footer()
-{
+void draw_footer() {
const char *app_name = "Task Tracker";
const char *app_version = "v1.0";
@@ -283,13 +471,11 @@ void draw_footer()
addch(ACS_LRCORNER);
}
-
WINDOW *create_newwin(int height, int width, int starty, int startx);
void destroy_win(WINDOW *local_win);
-int main(int argc, char *argv[])
-{
- fake_data();
+int main(int argc, char *argv[]) {
+ prototype();
return 0;
@@ -314,8 +500,6 @@ int main(int argc, char *argv[])
int rows;
int colums;
- fake_data();
-
ch = KEY_RESIZE;
do {
switch(ch)
@@ -355,10 +539,8 @@ int main(int argc, char *argv[])
return 0;
}
-
-
-WINDOW *create_newwin(int height, int width, int starty, int startx)
-{ WINDOW *local_win;
+WINDOW *create_newwin(int height, int width, int starty, int startx) {
+ WINDOW *local_win;
local_win = newwin(height, width, starty, startx);
box(local_win, 0 , 0); /* 0, 0 gives default characters
@@ -369,8 +551,7 @@ WINDOW *create_newwin(int height, int width, int starty, int startx)
return local_win;
}
-void destroy_win(WINDOW *local_win)
-{
+void destroy_win(WINDOW *local_win) {
/* box(local_win, ' ', ' '); : This won't produce the desired
* result of erasing the window. It will leave it's four corners
* and so an ugly remnant of window.