2 #include "headers/parser.h"
6 TodoList* cur_todolist;
7 TodoItem* cur_todoitem;
8 /* for use during processing */
12 char* read_file(char* file_name, long* size);
15 void enter_todolist(State* state, char* list_name);
16 void exit_todolist(State* state);
18 void enter_todoitem(State* state, char* item_name);
19 void exit_todoitem(State* state);
21 void set_description(State* state, char* description);
22 void set_due(State* state, char* due); // make an acc date struct later
23 void add_subtask(State* state, char* subtask_name, SubTaskState subtask_state);
25 /* callbacks to parser */
26 int enter_block(MD_BLOCKTYPE type, void* detail, void* userdata);
27 int leave_block(MD_BLOCKTYPE type, void* detail, void* userdata);
28 int enter_span(MD_SPANTYPE type, void* detail, void* userdata);
29 int leave_span(MD_SPANTYPE type, void* detail, void* userdata);
30 int text(MD_TEXTTYPE type, const MD_CHAR* text, MD_SIZE size, void* userdata);
31 void debug_log(const char* msg, void* userdata);
34 const MD_PARSER parser = {
49 begin_parse(char* board_path)
51 const char* input_buffer;
56 /* read entire file */
57 input_buffer = read_file(board_path, &input_size);
60 state.cur_todolist = NULL;
61 state.cur_todoitem = NULL;
63 new_board = malloc(sizeof(Board));
64 new_board->todolist_list = malloc(0);
65 new_board->todolist_count = 0;
66 state.board = new_board;
68 md_parse(input_buffer, input_size, &parser, &state);
71 exit_todolist(&state);
73 free((char*)input_buffer);
79 read_file(char* file_name, long* size)
80 { // apparently using seek isnt the greatest, may change to chunk reading later
85 file = fopen(file_name, "r");
87 perror("read_file > fopen");
91 fseek(file, 0, SEEK_END);
93 fseek(file, 0, SEEK_SET);
95 output = malloc(fsize+1); // maybe error check malloc
96 fread(output, 1, fsize, file);
98 printf("Something went wrong reading file\n");
103 output[fsize] = 0; // add null terminator
114 enter_todolist(State* state, char* list_name)
116 TodoList* new_todolist;
118 new_todolist = malloc(sizeof(TodoList));
119 new_todolist->list_name = list_name;
120 new_todolist->item_list = malloc(0);
121 new_todolist->item_count = 0;
123 state->cur_todolist = new_todolist;
127 exit_todolist(State* state)
129 #define sb state->board
131 if (state->cur_todolist == NULL) return;
133 exit_todoitem(state);
135 sb->todolist_count += 1;
136 sb->todolist_list = realloc(sb->todolist_list, sb->todolist_count*sizeof(TodoList*));
137 sb->todolist_list[sb->todolist_count-1] = state->cur_todolist;
138 state->cur_todolist = NULL;
144 enter_todoitem(State* state, char* item_name)
146 TodoItem* new_todoitem;
148 new_todoitem = malloc(sizeof(TodoItem));
149 new_todoitem->item_name = item_name;
150 new_todoitem->description = strdup("");
151 new_todoitem->due = strdup("");
152 new_todoitem->subtask_list = malloc(0);
153 new_todoitem->subtask_count = 0;
155 state->cur_todoitem = new_todoitem;
160 exit_todoitem(State* state)
162 #define st state->cur_todolist
164 if (state->cur_todoitem == NULL) return;
166 /* append current item to todo list */
168 st->item_list = realloc(st->item_list, st->item_count*sizeof(TodoItem*));
169 st->item_list[st->item_count-1] = state->cur_todoitem;
170 state->cur_todoitem = NULL;
176 set_description(State* state, char* description)
178 state->cur_todoitem->description = description;
182 set_due(State* state, char* due)
184 state->cur_todoitem->due = due;
188 add_subtask(State* state, char* subtask_name, SubTaskState subtask_state)
190 SubTask* new_subtask;
191 SubTask** subtask_list;
193 /* create new subtask */
194 new_subtask = malloc(sizeof(SubTask));
195 new_subtask->subtask_name = subtask_name;
196 new_subtask->done = subtask_state;
199 subtask_list = state->cur_todoitem->subtask_list;
201 state->cur_todoitem->subtask_count += 1;
202 subtask_list = realloc(subtask_list, state->cur_todoitem->subtask_count*sizeof(SubTask*));
203 subtask_list[state->cur_todoitem->subtask_count-1] = new_subtask;
205 state->cur_todoitem->subtask_list = subtask_list;
210 enter_block(MD_BLOCKTYPE type, void* detail, void* userdata)
216 leave_block(MD_BLOCKTYPE type, void* detail, void* userdata)
219 state = (State*)userdata;
225 MD_BLOCK_H_DETAIL* h_detail;
226 h_detail = ((MD_BLOCK_H_DETAIL*)detail);
228 switch(h_detail->level) {
234 exit_todolist(state);
235 enter_todolist(state, state->last_block_text);
239 exit_todoitem(state);
240 enter_todoitem(state, state->last_block_text);
247 set_description(state, state->last_block_text);
251 MD_BLOCK_LI_DETAIL* li_detail;
254 li_detail = ((MD_BLOCK_LI_DETAIL*)detail);
256 assert(li_detail->is_task != 0); // all lists should be task lists
258 done = li_detail->task_mark == ' ' ? SubTaskState_todo : SubTaskState_done;
260 add_subtask(state, state->last_block_text, done);
263 // no need for default case for now :>
269 enter_span(MD_SPANTYPE type, void* detail, void* userdata)
277 leave_span(MD_SPANTYPE type, void* detail, void* userdata)
280 state = (State*)userdata;
284 set_due(state, state->last_block_text);
291 text(MD_TEXTTYPE type, const MD_CHAR* text, MD_SIZE size, void* userdata){
296 state = (State*)userdata;
298 content = malloc(size*sizeof(char)+1);
299 memcpy(content, text, size);
302 /* printf("%s\n", content); */
303 state->last_block_text = content;
309 debug_log(const char* msg, void* userdata)
323 begin_write(char* board_path, Board* board)
324 { // TODO, make a backup file of board before write in case it crashes
328 file = fopen(board_path, "w+");
330 perror("begin_write > fopen");
334 for (int i = 0; i < board->todolist_count; i++) {
335 TodoList* cur_todolist = board->todolist_list[i];
337 fprintf(file, "## %s\n", cur_todolist->list_name);
339 for (int j = 0; j < cur_todolist->item_count; j++) {
340 TodoItem* cur_todoitem = cur_todolist->item_list[j];
342 fprintf(file, "### %s\n", cur_todoitem->item_name);
344 /* bug rn, for some reason date is being written as description too */
345 if (strlen(cur_todoitem->description) > 0) {
346 fprintf(file, "> %s\n", cur_todoitem->description);
348 if (strlen(cur_todoitem->due) > 0) {
349 fprintf(file, "**%s**\n", cur_todoitem->due);
352 for (int k = 0; k < cur_todoitem->subtask_count; k++) {
353 SubTask* cursubtask = cur_todoitem->subtask_list[k];
355 char done_char = (cursubtask->done == SubTaskState_done) ? 'X' : ' ';
356 fprintf(file, "- [%c] %s\n", done_char, cursubtask->subtask_name);
371 log_todo(Board* board)
373 for (int i = 0; i < board->todolist_count; i++) {
375 printf("List =-=-=-=-=-==-=-=-=-=-=-\n");
376 todolist = board->todolist_list[i];
377 printf("List name: %s\n", todolist->list_name);
378 printf("Num of items: %d\n", todolist->item_count);
380 for (int j = 0; j < todolist->item_count; j++) {
382 printf("Item =-=-=-=-=-\n");
383 todoitem = todolist->item_list[j];
384 printf("Item name: %s\n", todoitem->item_name);
385 printf("Description: %s\n", todoitem->description);
386 printf("Num of subtasks: %d\n", todoitem->subtask_count);
388 for (int k = 0; k < todoitem->subtask_count; k++) {
392 subtask = todoitem->subtask_list[k];
393 printf("Subtask: %s, %d\n", subtask->subtask_name, subtask->done);
400 free_board(Board* board)
401 { // all the fields are being leaked rn
403 for (int i = 0; i < board->todolist_count; i++) {
404 TodoList* cur_todolist = board->todolist_list[i];
406 /* free(cur_todolist->list_name); */
408 for (int j = 0; j < cur_todolist->item_count; j++) {
409 TodoItem* cur_todoitem = cur_todolist->item_list[j];
411 /* free(cur_todoitem->item_name); */
412 /* free(cur_todoitem->description); */
413 /* free(cur_todoitem->due); */
415 /* free subtask later too */
416 for (int k = 0; k < cur_todoitem->subtask_count; k++) {
417 SubTask* cur_subtask = cur_todoitem->subtask_list[k];
419 /* free(cur_subtask->subtask_name); */
430 /* free(board->board_name); */