GCC Code Coverage Report


Directory: ./
File: src/parsing/input_command.c
Date: 2024-06-05 00:36:48
Exec Total Coverage
Lines: 93 107 86.9%
Functions: 8 9 88.9%
Branches: 75 86 87.2%

Line Branch Exec Source
1 /*
2 ** EPITECH PROJECT, 2024
3 ** 42sh
4 ** File description:
5 ** The file containing the input_command functions
6 */
7 /**
8 * @file input_command.c
9 * @brief The file containing the input_command functions
10 */
11
12 #include "../../include/myshell.h"
13
14 /**
15 * @brief Initialize the input command
16 * @param command The command
17 * @return <b>input_command_t *</b> The input command
18 */
19 1153 input_command_t *init_input_command(char *command)
20 {
21 1153 input_command_t *input_command = malloc(sizeof(input_command_t));
22
23 1153 input_command->command = CALLOC(my_strlen(command) + 1, sizeof(char));
24 1153 input_command->args = NULL;
25 1153 input_command->left = NULL;
26 1153 input_command->right = NULL;
27 1153 input_command->left_type = 0;
28 1153 input_command->right_type = 0;
29 1153 input_command->current = input_command->command;
30 1153 return input_command;
31 }
32
33 /**
34 * @brief Check if there is an error in the input command
35 * @param input_command The input command
36 * @param command The command
37 * @param index The index
38 * @param inhibitors The inhibitors
39 * @return <b>int</b> <u>1</u> if there is an error, <u>0</u> otherwise
40 */
41 178451 static int check_error(input_command_t *input_command,
42 const char *command, int index, int inhibitors)
43 {
44
4/4
✓ Branch 0 taken 972 times.
✓ Branch 1 taken 177479 times.
✓ Branch 2 taken 720 times.
✓ Branch 3 taken 252 times.
178451 if (input_command->right_type != 0 &&
45
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 707 times.
720 inhibitors == 0 && command[index] == '>') {
46
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 6 times.
13 if (input_command->right[0] == '\0')
47 7 my_putstr_error("Missing name for redirect.\n");
48 else
49 6 my_putstr_error("Ambiguous output redirect.\n");
50 13 return 1;
51 }
52
3/4
✓ Branch 0 taken 769 times.
✓ Branch 1 taken 177669 times.
✓ Branch 2 taken 769 times.
✗ Branch 3 not taken.
178438 if (input_command->left_type != 0 &&
53
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 769 times.
769 inhibitors == 0 && command[index] == '<') {
54 if (input_command->left[0] == '\0')
55 my_putstr_error("Missing name for redirect.\n");
56 else
57 my_putstr_error("Ambiguous input redirect.\n");
58 return 1;
59 }
60 178438 return 0;
61 }
62
63 /**
64 * @brief Check if the character is a right redirection and
65 * change the input structure
66 * @param input_command The input command
67 * @param command The command
68 * @param index The index
69 * @return <b>int</b> <u>1</u> if the character is a right redirection,
70 * <u>0</u> otherwise
71 */
72 177773 static int right_redirection(input_command_t *input_command,
73 char *command, int *index)
74 {
75
4/4
✓ Branch 0 taken 100 times.
✓ Branch 1 taken 177673 times.
✓ Branch 2 taken 37 times.
✓ Branch 3 taken 63 times.
177773 if (command[*index] == '>' && command[*index + 1] == '>') {
76 37 input_command->right_type = 2;
77 37 input_command->right = CALLOC(my_strlen(command), sizeof(char));
78 37 input_command->current = input_command->right;
79 37 (*index)++;
80 37 return 1;
81 }
82
2/2
✓ Branch 0 taken 63 times.
✓ Branch 1 taken 177673 times.
177736 if (command[*index] == '>') {
83 63 input_command->right_type = 1;
84 63 input_command->right = CALLOC(my_strlen(command), sizeof(char));
85 63 input_command->current = input_command->right;
86 63 return 1;
87 }
88 177673 return 0;
89 }
90
91 /**
92 * @brief Check if the character is a left redirection and
93 * change the input structure
94 * @param input_command The input command
95 * @param command The command
96 * @param index The index
97 * @return <b>int</b> <u>1</u> if the character is a left redirection,
98 * <u>0</u> otherwise
99 */
100 177673 static int left_redirection(input_command_t *input_command,
101 char *command, int *index)
102 {
103
4/4
✓ Branch 0 taken 45 times.
✓ Branch 1 taken 177628 times.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 38 times.
177673 if (command[*index] == '<' && command[*index + 1] == '<') {
104 7 input_command->left_type = 2;
105 7 input_command->left = CALLOC(my_strlen(command), sizeof(char));
106 7 input_command->current = input_command->left;
107 7 (*index)++;
108 7 return 1;
109 }
110
2/2
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 177628 times.
177666 if (command[*index] == '<') {
111 38 input_command->left_type = 1;
112 38 input_command->left = CALLOC(my_strlen(command), sizeof(char));
113 38 input_command->current = input_command->left;
114 38 return 1;
115 }
116 177628 return 0;
117 }
118
119 /**
120 * @brief Add a character to the input command
121 * @param input_command The input command
122 * @param command The command
123 * @param index The index
124 * @param inhibitors The inhibitors
125 * @return <b>int</b> The start value
126 */
127 178438 static int add_char_to_input(input_command_t *input_command,
128 char *command, int *index, char *inhibitors)
129 {
130 static int start = 1;
131
132
4/4
✓ Branch 0 taken 177773 times.
✓ Branch 1 taken 665 times.
✓ Branch 2 taken 177673 times.
✓ Branch 3 taken 100 times.
356211 if (*inhibitors == 0 &&
133
2/2
✓ Branch 1 taken 45 times.
✓ Branch 2 taken 177628 times.
355446 (right_redirection(input_command, command, index) ||
134 177673 left_redirection(input_command, command, index))) {
135 145 start = 1;
136 145 return -1;
137 }
138
2/2
✓ Branch 0 taken 1291 times.
✓ Branch 1 taken 177002 times.
178293 if (input_command->current == input_command->command ||
139
5/6
✓ Branch 0 taken 252 times.
✓ Branch 1 taken 1039 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 252 times.
✓ Branch 4 taken 270 times.
✓ Branch 5 taken 769 times.
2330 (*inhibitors != 0 && *inhibitors != command[*index]) ||
140
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 270 times.
1309 my_char_is(command[*index], " \t\n\"\'\\()") == 0 || *inhibitors == 1) {
141 178023 my_add_chr(input_command->current, command[*index]);
142 178023 start = 0;
143 178023 return -1;
144 }
145
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 270 times.
270 if (*inhibitors != 0)
146 return -1;
147 270 return start;
148 }
149
150 /**
151 * @brief Update the inhibitors
152 * @param command The command
153 * @param index The index
154 * @param inhibitors The inhibitors
155 * @param end_inhibitors The end inhibitors
156 * @return <b>void</b>
157 */
158 178515 static int update_inhibitors(char *command, int index,
159 char *inhibitors)
160 {
161
4/4
✓ Branch 0 taken 678 times.
✓ Branch 1 taken 177837 times.
✓ Branch 2 taken 62 times.
✓ Branch 3 taken 616 times.
178515 if ((*inhibitors != 0 && *inhibitors == command[index]
162
5/6
✗ Branch 0 not taken.
✓ Branch 1 taken 62 times.
✓ Branch 2 taken 106 times.
✓ Branch 3 taken 178347 times.
✓ Branch 4 taken 11 times.
✓ Branch 5 taken 95 times.
178515 && *inhibitors != '\\') || (*inhibitors == '(' && command[index] == ')')) {
163 73 *inhibitors = 0;
164 73 return 1;
165 }
166
2/2
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 178419 times.
178442 if (*inhibitors == '\\') {
167 23 *inhibitors = 1;
168 23 return 0;
169 }
170
4/4
✓ Branch 0 taken 177837 times.
✓ Branch 1 taken 582 times.
✓ Branch 3 taken 98 times.
✓ Branch 4 taken 177739 times.
178419 if (*inhibitors == 0 && my_char_is(command[index], "\'\"\\(")) {
171 98 *inhibitors = command[index];
172 98 return 1;
173 }
174 178321 return 0;
175 }
176
177 /**
178 * @brief Validate the input command
179 * @param input_command The input command
180 * @param inhibitors The inhibitors
181 * @return <b>input_command_t *</b> The input command if it is valid,
182 * <u>NULL</u> otherwise
183 */
184 1140 input_command_t *validate_input_command(input_command_t *input_command,
185 char inhibitors)
186 {
187
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1138 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
1140 if (inhibitors != 0 && inhibitors != 1) {
188 2 my_fprintf(2, "Unmatched '%c'.\n", inhibitors);
189 2 return NULL;
190 }
191 1138 return input_command;
192 }
193
194 /**
195 * @brief Get the input command
196 * @param command The command
197 * @return <b>input_command_t *</b> The input command
198 */
199 1153 input_command_t *get_input_command(char *command)
200 {
201 1153 input_command_t *input_command = init_input_command(command);
202 1153 char inhibitors = 0;
203
204
6/6
✓ Branch 0 taken 193 times.
✓ Branch 1 taken 1178 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 1166 times.
✓ Branch 4 taken 13 times.
✓ Branch 5 taken 1153 times.
1371 while (command[0] == ' ' || command[0] == '\t' || command[0] == '\n')
205 218 command++;
206
2/2
✓ Branch 0 taken 178515 times.
✓ Branch 1 taken 1140 times.
179655 for (int index = 0; command[index] != '\0'; index++) {
207
2/2
✓ Branch 1 taken 171 times.
✓ Branch 2 taken 178344 times.
178515 if (update_inhibitors(command, index, &inhibitors)
208
2/2
✓ Branch 0 taken 64 times.
✓ Branch 1 taken 107 times.
171 && input_command->current != input_command->command)
209 64 continue;
210
2/2
✓ Branch 1 taken 13 times.
✓ Branch 2 taken 178438 times.
178451 if (check_error(input_command, command, index, inhibitors) == 1)
211 13 return NULL;
212
2/2
✓ Branch 1 taken 132 times.
✓ Branch 2 taken 178306 times.
178438 if (!add_char_to_input(input_command, command, &index, &inhibitors))
213 132 input_command->current = input_command->command;
214
2/2
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 178415 times.
178438 if (inhibitors == 1)
215 23 inhibitors = 0;
216 }
217 1140 return validate_input_command(input_command, inhibitors);
218 }
219
220 /**
221 * @brief Display the input command
222 * @note The function is used for debugging
223 * @param input_command The input command
224 * @return <b>void</b>
225 */
226 void display_input_command(input_command_t *input_command)
227 {
228 if (input_command == NULL)
229 return;
230 my_printf("Command: %s\n", input_command->command);
231 my_printf("Left: %s\n", input_command->left);
232 my_printf("Right: %s\n", input_command->right);
233 my_printf("Left type: %d\n", input_command->left_type);
234 my_printf("Right type: %d\n", input_command->right_type);
235 my_printf("Args: %S", input_command->args);
236 }
237