diff options
Diffstat (limited to '')
| -rw-r--r-- | src/questions.c | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/src/questions.c b/src/questions.c new file mode 100644 index 0000000..88671a7 --- /dev/null +++ b/src/questions.c | |||
| @@ -0,0 +1,92 @@ | |||
| 1 | #include "questions.h" | ||
| 2 | #include <stdio.h> | ||
| 3 | #include <stdlib.h> | ||
| 4 | #include <string.h> | ||
| 5 | |||
| 6 | #define MAX_LINE 512 | ||
| 7 | |||
| 8 | static int add_question(char ***arr, size_t *count, const char *text) { | ||
| 9 | char **tmp = realloc(*arr, (*count + 1) * sizeof(char *)); | ||
| 10 | if (!tmp) | ||
| 11 | return EXIT_FAILURE; | ||
| 12 | *arr = tmp; | ||
| 13 | |||
| 14 | (*arr)[*count] = malloc(strlen(text) + 1); | ||
| 15 | if (!(*arr)[*count]) | ||
| 16 | return EXIT_FAILURE; | ||
| 17 | |||
| 18 | strcpy((*arr)[*count], text); | ||
| 19 | (*count)++; | ||
| 20 | return EXIT_SUCCESS; | ||
| 21 | } | ||
| 22 | |||
| 23 | int load_questions(const char *filename, QuestionSet *qs) { | ||
| 24 | if (!filename || !qs) | ||
| 25 | return EXIT_FAILURE; | ||
| 26 | |||
| 27 | FILE *f = fopen(filename, "r"); | ||
| 28 | if (!f) | ||
| 29 | return EXIT_FAILURE; | ||
| 30 | |||
| 31 | qs->general = NULL; | ||
| 32 | qs->major = NULL; | ||
| 33 | qs->general_count = 0; | ||
| 34 | qs->major_count = 0; | ||
| 35 | |||
| 36 | char line[MAX_LINE]; | ||
| 37 | enum { NONE, GENERAL, MAJOR } mode = NONE; | ||
| 38 | |||
| 39 | while (fgets(line, sizeof(line), f)) { | ||
| 40 | line[strcspn(line, "\n")] = '\0'; | ||
| 41 | if (line[0] == '\0') | ||
| 42 | continue; | ||
| 43 | |||
| 44 | if (strcmp(line, "#GENERAL") == 0) { | ||
| 45 | mode = GENERAL; | ||
| 46 | continue; | ||
| 47 | } | ||
| 48 | if (strcmp(line, "#MAJOR") == 0) { | ||
| 49 | mode = MAJOR; | ||
| 50 | continue; | ||
| 51 | } | ||
| 52 | |||
| 53 | int res = EXIT_FAILURE; | ||
| 54 | switch (mode) { | ||
| 55 | case GENERAL: | ||
| 56 | res = add_question(&qs->general, &qs->general_count, line); | ||
| 57 | break; | ||
| 58 | case MAJOR: | ||
| 59 | res = add_question(&qs->major, &qs->major_count, line); | ||
| 60 | break; | ||
| 61 | default: | ||
| 62 | continue; // ignore lines before section | ||
| 63 | } | ||
| 64 | |||
| 65 | if (res != EXIT_SUCCESS) { | ||
| 66 | fclose(f); | ||
| 67 | free_questions(qs); | ||
| 68 | return EXIT_FAILURE; | ||
| 69 | } | ||
| 70 | } | ||
| 71 | |||
| 72 | fclose(f); | ||
| 73 | return (qs->general_count && qs->major_count) ? EXIT_SUCCESS : EXIT_FAILURE; | ||
| 74 | } | ||
| 75 | |||
| 76 | void free_questions(QuestionSet *qs) { | ||
| 77 | if (!qs) | ||
| 78 | return; | ||
| 79 | |||
| 80 | for (size_t i = 0; i < qs->general_count; i++) | ||
| 81 | free(qs->general[i]); | ||
| 82 | for (size_t i = 0; i < qs->major_count; i++) | ||
| 83 | free(qs->major[i]); | ||
| 84 | |||
| 85 | free(qs->general); | ||
| 86 | free(qs->major); | ||
| 87 | |||
| 88 | qs->general = NULL; | ||
| 89 | qs->major = NULL; | ||
| 90 | qs->general_count = 0; | ||
| 91 | qs->major_count = 0; | ||
| 92 | } | ||
