summaryrefslogtreecommitdiffstats
path: root/src/questions.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/questions.c92
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
8static 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
23int 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
76void 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}