diff --git a/structure.c b/structure.c deleted file mode 100644 index 560ccf5..0000000 --- a/structure.c +++ /dev/null @@ -1,485 +0,0 @@ -/* - * Colloscope - A program that generates a colloscope for French 'classes prépas' - * Copyright (C) 2024 Alexandre Aboujaib - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - - -#include -#include -#include -#include -#include - -#include "logger.h" -#include "structure.h" - -//static int width = 1200; -//static int height = 900; -int date_dist(date d1, date d2) { /* returns distance between d1 and d2 in days - if d2 is sooner than d1, it will return -1 */ - if(d2.month == d1.month && d2.year == d1.year) { - if(d2.day < d1.day) { - return -1; - } - return d2.day - d1.day; - } else { - int is_31 = 0; - if(d1.month == 1 || d1.month == 3 || d1.month == 5 || d1.month == 7 || d1.month == 8 || d1.month == 10 || d1.month == 12) { - is_31 = 1; - } else { - is_31 = (d1.month == 2)*(-2) + (d1.month == 2 && d1.year%4 == 0 && d1.year%100 != 0); - } - if(d2.month - d1.month < 0 && d2.year <= d1.year) { - return -1; - } else if(d2.month - d1.month == 1 && d2.year == d1.year) { - return d2.day + (30 + is_31 - d1.day); - } else { - date copy; - copy.day = d1.day; - copy.month = d1.month; - copy.year = d1.year; - copy.month = (copy.month + 1); - if(copy.month == 13) { - copy.month = 1; - copy.year += 1; - } - return (30 + is_31 + date_dist(copy, d2)); - } - } -} - -bool is_sorted(creneau* edt, int len) { - for(int i = 1; i < len; i++) { - if(date_dist(edt[i-1].date, edt[i].date) == -1) { - warn("Anomaly detected at lane %d (dates are not sorted in ascending order) :", i); - warn("%d %d %d %d", edt[i-1].date.hour, edt[i-1].date.day, edt[i-1].date.month, edt[i-1].date.year); - warn("%d %d %d %d", edt[i].date.hour, edt[i].date.day, edt[i].date.month, edt[i].date.year); - warn("%d %d %d %d", edt[i+1].date.hour, edt[i+1].date.day, edt[i+1].date.month, edt[i+1].date.year); - return false; - } - } - info("No problem detected"); - return true; -} - -creneau* import_creneaux(char* filename, int size) { - // import creneau data from a file - // see file.txt for an example - FILE* ptr = fopen(filename, "r"); - char c = fgetc(ptr); - - creneau* edt = malloc(sizeof(creneau)*size); - int i = 0; - int to_fill = 0; - - int buffer = 0; - - while(c != EOF && c != '$') { - if((int)(c) >= 48 && (int)(c) <= 57) { - buffer *= 10; - buffer += (int)(c) - 48; - } else { - if(to_fill == 0) { - //printf("%d\n", i); - edt[i].date.hour = buffer; - edt[i].group = 0; - edt[i].name = malloc(sizeof(char)*35); - edt[i].name[0] = 'n'; - edt[i].name[1] = 'o'; - edt[i].name[2] = 'n'; - edt[i].name[3] = 'e'; - edt[i].name[4] = '\0'; - edt[i].namelen = 4; - edt[i].mat = NOTHING; - edt[i].salle.building = 'N'; - edt[i].salle.id = 0; - edt[i].length = 1; - } else if(to_fill == 1) { - edt[i].date.day = buffer; - } else if(to_fill == 2) { - edt[i].date.month = buffer; - } else if(to_fill == 3) { - edt[i].date.year = buffer; - } else { - edt[i].length++; - } - to_fill++; - buffer = 0; - if(c == '\n') { - i++; - to_fill = 0; - } - } - c = fgetc(ptr); - } - - fclose(ptr); - - if(!is_sorted(edt, size)) { - assert(0); - } - return edt; -} - -bool str_equal(char* s1, char* s2) { - // note : s1 and s2 must be valid strings (aka have \0 at the end) - if((int)(s1[0]) == 0 || (int)(s2[0]) == 0) { - return ((int)(s1[0]) == 0 && (int)(s2[0]) == 0); - } else if(s1[0] != s2[0]) { - return false; - } - return str_equal(&s1[1], &s2[1]); -} - -void str_copy(char* src, int l1, char* dest) { - /* put the word src with length l1, \0 NOT included, in dest */ - for(int i = 0; i <= l1; i++) { - dest[i] = src[i]; - } - dest[l1] = '\0'; -} - -colleur* import_colleurs(char* filename, int n_colleurs, int max_available) { - /* - - file has the following format : - name - mat - dates (date*) - - - name2 - mat2 - dates2 - - - name3 - ... - $ - - */ - FILE* ptr = fopen(filename, "r"); - char c = fgetc(ptr); - // {char* name; int namelen; topic mat; date* disp; int n_disp;} - colleur* res = malloc(sizeof(colleur)*n_colleurs); - - char* word = malloc(sizeof(char)*30); - int wordlen = 0; - - int buffer = 0; - - int date_ptr = 0; - - int current = 0; // 0 = name, 1 = mat, 2+ = dates - int colleur_ptr = 0; - - while(c != EOF && c != '$') { - if(c == '\n') { - if(current == 0) { - word[wordlen] = '\0'; - res[colleur_ptr].name = malloc(sizeof(char)*30); - str_copy(word, wordlen, res[colleur_ptr].name); - res[colleur_ptr].namelen = wordlen; - res[colleur_ptr].id = colleur_ptr; - } else if(current == 1) { - if(word[0] == 'M') { // math - res[colleur_ptr].mat = MATH; - } else if(word[0] == 'P') { // physics - res[colleur_ptr].mat = PHYSICS; - } else if(word[0] == 'E') { // english - res[colleur_ptr].mat = ENGLISH; - } else if(word[0] == 'I') { // info - res[colleur_ptr].mat = INFO; - } else { - word[wordlen] = '\0'; - fatal("Wait that's illegal (%s)", word); - assert(0); - } - res[colleur_ptr].disp = malloc(sizeof(date)*max_available); - } else { - res[colleur_ptr].disp[current-2].year = buffer; - } - current++; - wordlen = 0; - buffer = 0; - date_ptr = 0; - } else if(c == '+') { - res[colleur_ptr].n_disp = current-2; - current = 0; - colleur_ptr++; - - c = fgetc(ptr); // always a '\n', this to avoid some seg fault - } else { - if(current <= 1) { - word[wordlen] = c; - wordlen++; - } else { - if((int)(c) >= 48 && (int)(c) <= 57) { - buffer *= 10; - buffer += (int)(c) - 48; - } else { - if(date_ptr == 0) { - res[colleur_ptr].disp[current-2].hour = buffer; - } else if(date_ptr == 1) { - res[colleur_ptr].disp[current-2].day = buffer; - } else if(date_ptr == 2) { - res[colleur_ptr].disp[current-2].month = buffer; - } else { - fatal("Oh no (%d)", date_ptr); - assert(0); - } - buffer = 0; - date_ptr++; - } - } - } - //printf("%c", c); - c = fgetc(ptr); - } - // {char* name; int namelen; topic mat; date* disp; int n_disp;} - - info("Successfully imported colleurs"); - fclose(ptr); - free(word); - - return res; -} - -date increment_date(date d, int inc) { - int remaining = inc; - date res = d; - int delta_day = 0; - while(remaining > 0) { - res.day++; - delta_day = (res.month == 1 || res.month == 3 || res.month == 5 || res.month == 7 || res.month == 8 || res.month == 10 || res.month == 12) - 2*(res.month == 2) + (res.month == 2 && res.year%4 == 0 && res.year%100 != 0); - // sweet jesus - if(res.day > 30 + delta_day) { - res.day = 1; - if(res.month == 12) { - res.month = 1; - res.year++; - } else { - res.month++; - } - } - remaining--; - } - return res; -} - -creneau* import_creneaux_oneweek(char* filename, int len_file, int n_weeks) { - // import creneau data from a file then copy paste it for specified amount of weeks - FILE* ptr = fopen(filename, "r"); - char c = fgetc(ptr); - - creneau* edt = malloc(sizeof(creneau)*len_file*n_weeks); - int i = 0; - int to_fill = 0; - - int buffer = 0; - - while(c != EOF && c != '$') { - if((int)(c) >= 48 && (int)(c) <= 57) { - buffer *= 10; - buffer += (int)(c) - 48; - } else { - if(to_fill == 0) { - //printf("%d\n", i); - edt[i].date.hour = buffer; - edt[i].group = 0; - edt[i].name = malloc(sizeof(char)*35); - edt[i].name[0] = 'n'; - edt[i].name[1] = 'o'; - edt[i].name[2] = 'n'; - edt[i].name[3] = 'e'; - edt[i].name[4] = '\0'; - edt[i].namelen = 4; - edt[i].mat = NOTHING; - edt[i].salle.building = 'N'; - edt[i].salle.id = 0; - edt[i].length = 1; - } else if(to_fill == 1) { - edt[i].date.day = buffer; - } else if(to_fill == 2) { - edt[i].date.month = buffer; - } else if(to_fill == 3) { - edt[i].date.year = buffer; - } else { - edt[i].length++; - } - to_fill++; - buffer = 0; - if(c == '\n') { - i++; - to_fill = 0; - } - } - c = fgetc(ptr); - } - fclose(ptr); - - for(int k = 1; k < n_weeks; k++) { - for(int i = 0; i < len_file; i++) { - edt[k*len_file+i].date = increment_date(edt[i].date, 7*k); - edt[k*len_file+i].group = 0; - edt[k*len_file+i].name = malloc(sizeof(char)*35); - edt[k*len_file+i].name[0] = 'n'; - edt[k*len_file+i].name[1] = 'o'; - edt[k*len_file+i].name[2] = 'n'; - edt[k*len_file+i].name[3] = 'e'; - edt[k*len_file+i].name[4] = '\0'; - edt[k*len_file+i].namelen = 4; - edt[k*len_file+i].mat = NOTHING; - edt[k*len_file+i].salle.building = 'N'; - edt[k*len_file+i].salle.id = 0; - edt[k*len_file+i].length = edt[i].length; - } - } - - /*for(int k = 0; k < len_file*n_weeks; k++) { - printf("%d %d %d %d %d %d\n", edt[k].date.hour, edt[k].date.day, edt[k].date.month, edt[k].date.year, edt[k].group, (int)(edt[k].mat)); - }*/ - - if(!is_sorted(edt, n_weeks*len_file)) { - assert(0); - } - info("Imported creneaux successfully"); - return edt; -} - -void expand(colleur* guy, int id, int n_weeks) { - int len_1st = guy[id].n_disp; - date* new = malloc(sizeof(date)*len_1st*n_weeks); - - for(int b = 0; b < len_1st; b++) { - new[b] = guy[id].disp[b]; - } - for(int week = 1; week < n_weeks; week++) { - for(int i = 0; i < len_1st; i++) { - new[week*len_1st+i] = increment_date(guy[id].disp[i], 7*week); - } - } - - free(guy[id].disp); - guy[id].n_disp *= n_weeks; - guy[id].disp = new; -} - -colleur* import_colleurs_oneweek(char* filename, int n_colleurs, int n_weeks, int len_oneweek) { - // same as before, but each colleur only set his/her creneaux for the 1st week - FILE* ptr = fopen(filename, "r"); - char c = fgetc(ptr); - // {char* name; int namelen; topic mat; date* disp; int n_disp;} - colleur* res = malloc(sizeof(colleur)*n_colleurs); - - char* word = malloc(sizeof(char)*30); - int wordlen = 0; - - int buffer = 0; - - int date_ptr = 0; - - int current = 0; // 0 = name, 1 = mat, 2+ = dates - int colleur_ptr = 0; - - while(c != EOF && c != '$') { - if(c == '\n') { - if(current == 0) { - word[wordlen] = '\0'; - res[colleur_ptr].name = malloc(sizeof(char)*30); - str_copy(word, wordlen, res[colleur_ptr].name); - res[colleur_ptr].namelen = wordlen; - } else if(current == 1) { - if(word[0] == 'M') { // math - res[colleur_ptr].mat = MATH; - } else if(word[0] == 'P') { // physics - res[colleur_ptr].mat = PHYSICS; - } else if(word[0] == 'E') { // english - res[colleur_ptr].mat = ENGLISH; - } else if(word[0] == 'I') { // info - res[colleur_ptr].mat = INFO; - } else { - word[wordlen] = '\0'; - fatal("Wait that's illegal (%s)", word); - assert(0); - } - res[colleur_ptr].disp = malloc(sizeof(date)*len_oneweek); - res[colleur_ptr].id = colleur_ptr; - } else { - res[colleur_ptr].disp[current-2].year = buffer; - } - current++; - wordlen = 0; - buffer = 0; - date_ptr = 0; - } else if(c == '+') { - res[colleur_ptr].n_disp = current-2; - current = 0; - colleur_ptr++; - - c = fgetc(ptr); // always a '\n', this to avoid some seg fault - } else { - if(current <= 1) { - word[wordlen] = c; - wordlen++; - } else { - if((int)(c) >= 48 && (int)(c) <= 57) { - buffer *= 10; - buffer += (int)(c) - 48; - } else { - if(date_ptr == 0) { - res[colleur_ptr].disp[current-2].hour = buffer; - } else if(date_ptr == 1) { - res[colleur_ptr].disp[current-2].day = buffer; - } else if(date_ptr == 2) { - res[colleur_ptr].disp[current-2].month = buffer; - } else { - fatal("Oh no (%d)", date_ptr); - assert(0); - } - buffer = 0; - date_ptr++; - } - } - } - //printf("%c", c); - c = fgetc(ptr); - } - // {char* name; int namelen; topic mat; date* disp; int n_disp;} - - for(int c = 0; c < n_colleurs; c++) { - expand(res, c, n_weeks); - } - - fclose(ptr); - free(word); - - info("Imported colleurs with no problems"); - return res; -} - -int str_to_int(char* s) { - char c = 'e'; - int i = 0; - int buffer = 0; - while(c != '\0') { - c = s[i]; - buffer *= 10; - if((int)(c) >= 48 && (int)(c) <= 57) { - buffer += (int)(c)-48; - } - i++; - } - return buffer/10; -}