/* * INPUT: linked list of subjects * OUTPUT: ll of events to iCal * ll of updated subjects to db for next day * return events_ll to caller(ui)?? * */ #include "planner.h" // for subject and event structs #include "llist.h" #include #include #include #include #include #include const uint intervalLen = 45; // min const uint pauseLen = 10; // const char taskFormat[] = "Task { %.64s = {\n created={%lu},\n deadline={%lu},\n " "priority={%d},\n spare={%lu}\n}\n"; const char eventFormat[] = "Event { %s = {\n start={%s},\n end={%s},\n spare={%lu}\n}\n"; void llistPrintT(llist *head) { llist *c = head; while (c != NULL) { printTask((Task *)c->data); c = c->next; } } // print Event to stdout void printEvent(Event *s) { char st[26]; char e[26]; ctime_r(&s->plannedStartTime, st); ctime_r(&s->plannedEndTime, e); printf(eventFormat, s->task->name, st, e, s->spare); // printTask(s->task); } void llistPrintE(llist *head) { llist *c = head; while (c != NULL) { printEvent((Event *)c->data); c = c->next; } } void freeEvent(Event *e) { free(e->task); free(e); } void llistFreeE(llist *head) { while (head != NULL) { free((Event *)head->data); llist *tmp = head; head = head->next; free(tmp); } } void llistFreeT(llist *head) { while (head != NULL) { free(head->data); llist *tmp = head; head = head->next; free(tmp); } } void planLog(char *msg, bool e) { if (!e) printf("[Planner][log] %s\n", msg); else fprintf(stderr, "==== [Planner][Err] %s\n", msg); } Event *newEvent(Task *t, time_t s, time_t e, uint64_t sp) { Event *r = (Event *)malloc(sizeof(Event)); if (r != NULL) { r->task = t; r->plannedStartTime = s; r->plannedEndTime = e; r->spare = sp; } return r; } /* * creat new task with name n created c deadline d priority p spare sp */ Task *newTask(char *n, time_t c, time_t d, int p, uint64_t sp) { Task *r = (Task *)malloc(sizeof(Task)); if (r != NULL) { r->created = c; r->deadline = d; r->priority = p; r->spare = sp; r->name = n; } return r; } /* * create deepCopy of task * !! r->name is malloced */ Task *copyTask(Task *t) { Task *r = malloc(sizeof(Task)); if (r != NULL) { r->name = strdup(t->name); r->created = t->created; r->deadline = t->deadline; r->priority = t->priority; r->spare = t->spare; } return r; } void printTask(Task *s) { printf(taskFormat, s->name, s->created, s->deadline, s->priority, s->spare); } // return string representation of task // NULL on failure // free string after use char *taskToStr(Task *t) { char *r = malloc(sizeof(char) * strlen(taskFormat) + 0x200); if (r != NULL) { sprintf(r, taskFormat, t->name, t->created, t->deadline, t->priority, t->spare); } return r; } // for llist // compare task by name int cmpTaskN(const void *a, const void *b) { Task *aa = (Task *)a; Task *bb = (Task *)b; return strcmp(aa->name, bb->name); } // compare task by priority int cmpTaskP(const void *a, const void *b) { Task *aa = (Task *)a; Task *bb = (Task *)b; return bb->priority - aa->priority; } // cmp event by task name int cmpEvent(const void *a, const void *b) { Event *aa = (Event *)a; Event *bb = (Event *)b; return cmpTaskN(aa->task, bb->task); } llist *genPlan(llist *head, time_t timeAvail) { // map llist to pointer arr & sort by priority // second arr sorted bby name int lLen = llistLen(head); planLog("genpla: got llist\n", false); printf("len: %d\n", lLen); llistPrintT(head); // Task *sortedNames = calloc(lLen, sizeof(Task)); Task *sortedPrio = calloc(lLen, sizeof(Task)); if (/*sortedNames == NULL ||*/ sortedPrio == NULL) { planLog("gen plan : calloc failed!!\n", true); return NULL; } // add Tasks from llist to arr llist *c = head; for (int i = 0; c != NULL; i++) { // sortedNames[i] = *copyTask(c->data); // sortedPrio[i] = *copyTask(c->data); // sortedNames[i] = *(Task *)c->data; sortedPrio[i] = *(Task *)c->data; c = c->next; } // sort // qsort(sortedNames, lLen, sizeof(Task), cmpTaskN); qsort(sortedPrio, lLen, sizeof(Task), cmpTaskP); // // test print // planLog("sortendName", 0); // for (int i = 0; i < lLen; i++) { // printTask(sortedNames + i); // } planLog("sortendPrio", 0); for (int i = 0; i < lLen; i++) { printTask(sortedPrio + i); } planLog("creating eventList", false); // genertate plan basen on priorities and available time time_t now = time(NULL); struct tm *lc = localtime(&now); llist *events_ll = llistNew(NULL, cmpEvent); if (events_ll == NULL) { exit(1); } // time_t avail = mktime(timeAvail); time_t start, end; // (mktime(lc) < mktime(timeAvail)) do { start = mktime(lc); // start now lc->tm_min += intervalLen; end = mktime(lc); // llist *tmp = llistGet(head, sortedPrio); Event *c = NULL; if (tmp != NULL) { c = newEvent(tmp->data, start, end, 0); // use elem with wighest priority } llistAppend(events_ll, c); // printEvent(c); // printEvent((Event *)((events_ll)->next)->data); // decrement priority of first elem and resort list (*sortedPrio).priority -= 1; qsort(sortedPrio, lLen, sizeof(Task), cmpTaskP); lc->tm_min += pauseLen; // add pause } while (mktime(lc) < timeAvail); // for (int i = 0; i < lLen; i++) { // time_t start = mktime(lc); // // printf("start:: %s\n", ctime(&start)); // lc->tm_min += 45; // time_t end = mktime(lc); // printf("end:: %s\n", ctime(&end)); // // Event *c = newEvent(sortedPrio + i, start, end, 0); // printEvent(c); // lc->tm_min += 15; // llistAppend(events_ll, c); // } // // free empty head llist *tmp = events_ll; events_ll = events_ll->next; tmp->next = NULL; llistFreeE(tmp); llistPrintE(events_ll); // update prioriteis in original llist for (int i = 0; i < lLen; i++) { llist *tmp = llistGet(head, sortedPrio + i); if (tmp != NULL) { ((Task *)(tmp->data))->priority = sortedPrio[i].priority; } } free(sortedPrio); planLog("END GEN PLAN", 0); // llistFreeT(head); // send updated tasks to db for storage return events_ll; }