summaryrefslogtreecommitdiffstats
path: root/src/questions.c
diff options
context:
space:
mode:
authorFilip Wandzio <contact@philw.dev>2026-03-01 17:45:00 +0100
committerFilip Wandzio <contact@philw.dev>2026-03-01 17:45:00 +0100
commit9e9c1b21569faeabd33716e4153a881e2eed7134 (patch)
treef3a7ad21aed4b1c4f51c3ee308ffef88430deafc /src/questions.c
parent57b077a4788b7fb5ed6add1df4ba3f15c9e6349b (diff)
downloadysnp-9e9c1b21569faeabd33716e4153a881e2eed7134.tar.gz
ysnp-9e9c1b21569faeabd33716e4153a881e2eed7134.zip
Separate quiz logic from main function fo dedicated moduleHEADmaster
Signed-off-by: Filip Wandzio <contact@philw.dev>
Diffstat (limited to '')
-rw-r--r--src/questions.c160
1 files changed, 83 insertions, 77 deletions
diff --git a/src/questions.c b/src/questions.c
index 88671a7..491c106 100644
--- a/src/questions.c
+++ b/src/questions.c
@@ -5,88 +5,94 @@
5 5
6#define MAX_LINE 512 6#define MAX_LINE 512
7 7
8static int add_question(char ***arr, size_t *count, const char *text) { 8static int add_question(char*** arr, size_t* count, const char* text)
9 char **tmp = realloc(*arr, (*count + 1) * sizeof(char *)); 9{
10 if (!tmp) 10 char** tmp = realloc(*arr, (*count + 1) * sizeof(char*));
11 return EXIT_FAILURE; 11 if (!tmp)
12 *arr = tmp; 12 return EXIT_FAILURE;
13 13 *arr = tmp;
14 (*arr)[*count] = malloc(strlen(text) + 1); 14
15 if (!(*arr)[*count]) 15 (*arr)[*count] = malloc(strlen(text) + 1);
16 return EXIT_FAILURE; 16 if (!(*arr)[*count])
17 17 return EXIT_FAILURE;
18 strcpy((*arr)[*count], text); 18
19 (*count)++; 19 strcpy((*arr)[*count], text);
20 return EXIT_SUCCESS; 20 (*count)++;
21 return EXIT_SUCCESS;
21} 22}
22 23
23int load_questions(const char *filename, QuestionSet *qs) { 24int load_questions(const char* filename, QuestionSet* qs)
24 if (!filename || !qs) 25{
25 return EXIT_FAILURE; 26 if (!filename || !qs)
26 27 return EXIT_FAILURE;
27 FILE *f = fopen(filename, "r"); 28
28 if (!f) 29 FILE* f = fopen(filename, "r");
29 return EXIT_FAILURE; 30 if (!f)
30 31 return EXIT_FAILURE;
31 qs->general = NULL; 32
32 qs->major = NULL; 33 qs->general = NULL;
33 qs->general_count = 0; 34 qs->major = NULL;
34 qs->major_count = 0; 35 qs->general_count = 0;
35 36 qs->major_count = 0;
36 char line[MAX_LINE]; 37
37 enum { NONE, GENERAL, MAJOR } mode = NONE; 38 char line[MAX_LINE];
38 39 enum { NONE, GENERAL, MAJOR } mode = NONE;
39 while (fgets(line, sizeof(line), f)) { 40
40 line[strcspn(line, "\n")] = '\0'; 41 while (fgets(line, sizeof(line), f)) {
41 if (line[0] == '\0') 42 line[strcspn(line, "\n")] = '\0';
42 continue; 43 if (line[0] == '\0')
43 44 continue;
44 if (strcmp(line, "#GENERAL") == 0) { 45
45 mode = GENERAL; 46 if (strcmp(line, "#GENERAL") == 0) {
46 continue; 47 mode = GENERAL;
47 } 48 continue;
48 if (strcmp(line, "#MAJOR") == 0) { 49 }
49 mode = MAJOR; 50 if (strcmp(line, "#MAJOR") == 0) {
50 continue; 51 mode = MAJOR;
51 } 52 continue;
52 53 }
53 int res = EXIT_FAILURE; 54
54 switch (mode) { 55 int res = EXIT_FAILURE;
55 case GENERAL: 56 switch (mode) {
56 res = add_question(&qs->general, &qs->general_count, line); 57 case GENERAL:
57 break; 58 res = add_question(
58 case MAJOR: 59 &qs->general, &qs->general_count, line);
59 res = add_question(&qs->major, &qs->major_count, line); 60 break;
60 break; 61 case MAJOR:
61 default: 62 res = add_question(
62 continue; // ignore lines before section 63 &qs->major, &qs->major_count, line);
63 } 64 break;
64 65 default:
65 if (res != EXIT_SUCCESS) { 66 continue;
66 fclose(f); 67 }
67 free_questions(qs); 68
68 return EXIT_FAILURE; 69 if (res != EXIT_SUCCESS) {
69 } 70 fclose(f);
70 } 71 free_questions(qs);
71 72 return EXIT_FAILURE;
72 fclose(f); 73 }
73 return (qs->general_count && qs->major_count) ? EXIT_SUCCESS : EXIT_FAILURE; 74 }
75
76 fclose(f);
77 return (qs->general_count && qs->major_count) ? EXIT_SUCCESS
78 : EXIT_FAILURE;
74} 79}
75 80
76void free_questions(QuestionSet *qs) { 81void free_questions(QuestionSet* qs)
77 if (!qs) 82{
78 return; 83 if (!qs)
84 return;
79 85
80 for (size_t i = 0; i < qs->general_count; i++) 86 for (size_t i = 0; i < qs->general_count; i++)
81 free(qs->general[i]); 87 free(qs->general[i]);
82 for (size_t i = 0; i < qs->major_count; i++) 88 for (size_t i = 0; i < qs->major_count; i++)
83 free(qs->major[i]); 89 free(qs->major[i]);
84 90
85 free(qs->general); 91 free(qs->general);
86 free(qs->major); 92 free(qs->major);
87 93
88 qs->general = NULL; 94 qs->general = NULL;
89 qs->major = NULL; 95 qs->major = NULL;
90 qs->general_count = 0; 96 qs->general_count = 0;
91 qs->major_count = 0; 97 qs->major_count = 0;
92} 98}