GCC Code Coverage Report


Directory: ./
File: src/parsing/input_command.c
Date: 2024-05-07 14:54:03
Exec Total Coverage
Lines: 96 107 89.7%
Functions: 8 9 88.9%
Branches: 77 86 89.5%

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 1280 input_command_t *init_input_command(char *command)
20 {
21 1280 input_command_t *input_command = malloc(sizeof(input_command_t));
22
23 1280 input_command->command = CALLOC(my_strlen(command) + 1, sizeof(char));
24 1280 input_command->args = NULL;
25 1280 input_command->left = NULL;
26 1280 input_command->right = NULL;
27 1280 input_command->left_type = 0;
28 1280 input_command->right_type = 0;
29 1280 input_command->current = input_command->command;
30 1280 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 42833 static int check_error(input_command_t *input_command,
42 const char *command, int index, int inhibitors)
43 {
44
4/4
✓ Branch 0 taken 1175 times.
✓ Branch 1 taken 41658 times.
✓ Branch 2 taken 855 times.
✓ Branch 3 taken 320 times.
42833 if (input_command->right_type != 0 &&
45
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 843 times.
855 inhibitors == 0 && command[index] == '>') {
46
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 8 times.
12 if (input_command->right[0] == '\0')
47 4 my_putstr_error("Missing name for redirect.\n");
48 else
49 8 my_putstr_error("Ambiguous output redirect.\n");
50 12 return 1;
51 }
52
3/4
✓ Branch 0 taken 481 times.
✓ Branch 1 taken 42340 times.
✓ Branch 2 taken 481 times.
✗ Branch 3 not taken.
42821 if (input_command->left_type != 0 &&
53
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 480 times.
481 inhibitors == 0 && command[index] == '<') {
54
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (input_command->left[0] == '\0')
55 my_putstr_error("Missing name for redirect.\n");
56 else
57 1 my_putstr_error("Ambiguous input redirect.\n");
58 1 return 1;
59 }
60 42820 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 40833 static int right_redirection(input_command_t *input_command,
73 char *command, int *index)
74 {
75
4/4
✓ Branch 0 taken 115 times.
✓ Branch 1 taken 40718 times.
✓ Branch 2 taken 39 times.
✓ Branch 3 taken 76 times.
40833 if (command[*index] == '>' && command[*index + 1] == '>') {
76 39 input_command->right_type = 2;
77 39 input_command->right = CALLOC(my_strlen(command), sizeof(char));
78 39 input_command->current = input_command->right;
79 39 (*index)++;
80 39 return 1;
81 }
82
2/2
✓ Branch 0 taken 76 times.
✓ Branch 1 taken 40718 times.
40794 if (command[*index] == '>') {
83 76 input_command->right_type = 1;
84 76 input_command->right = CALLOC(my_strlen(command), sizeof(char));
85 76 input_command->current = input_command->right;
86 76 return 1;
87 }
88 40718 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 40718 static int left_redirection(input_command_t *input_command,
101 char *command, int *index)
102 {
103
4/4
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 40688 times.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 22 times.
40718 if (command[*index] == '<' && command[*index + 1] == '<') {
104 8 input_command->left_type = 2;
105 8 input_command->left = CALLOC(my_strlen(command), sizeof(char));
106 8 input_command->current = input_command->left;
107 8 (*index)++;
108 8 return 1;
109 }
110
2/2
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 40688 times.
40710 if (command[*index] == '<') {
111 22 input_command->left_type = 1;
112 22 input_command->left = CALLOC(my_strlen(command), sizeof(char));
113 22 input_command->current = input_command->left;
114 22 return 1;
115 }
116 40688 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 42820 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 40833 times.
✓ Branch 1 taken 1987 times.
✓ Branch 2 taken 40718 times.
✓ Branch 3 taken 115 times.
83653 if (*inhibitors == 0 &&
133
2/2
✓ Branch 1 taken 30 times.
✓ Branch 2 taken 40688 times.
81551 (right_redirection(input_command, command, index) ||
134 40718 left_redirection(input_command, command, index))) {
135 145 start = 1;
136 145 return -1;
137 }
138
2/2
✓ Branch 0 taken 1378 times.
✓ Branch 1 taken 41297 times.
42675 if (input_command->current == input_command->command ||
139
5/6
✓ Branch 0 taken 320 times.
✓ Branch 1 taken 1058 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 320 times.
✓ Branch 4 taken 275 times.
✓ Branch 5 taken 783 times.
2436 (*inhibitors != 0 && *inhibitors != command[*index]) ||
140
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 275 times.
1333 my_char_is(command[*index], " \t\n\"\'\\()") == 0 || *inhibitors == 1) {
141 42400 my_add_chr(input_command->current, command[*index]);
142 42400 start = 0;
143 42400 return -1;
144 }
145
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 275 times.
275 if (*inhibitors != 0)
146 return -1;
147 275 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 42920 static int update_inhibitors(char *command, int index,
159 char *inhibitors)
160 {
161
4/4
✓ Branch 0 taken 1991 times.
✓ Branch 1 taken 40929 times.
✓ Branch 2 taken 128 times.
✓ Branch 3 taken 1863 times.
42920 if ((*inhibitors != 0 && *inhibitors == command[index]
162
5/6
✗ Branch 0 not taken.
✓ Branch 1 taken 128 times.
✓ Branch 2 taken 649 times.
✓ Branch 3 taken 42143 times.
✓ Branch 4 taken 49 times.
✓ Branch 5 taken 600 times.
42920 && *inhibitors != '\\') || (*inhibitors == '(' && command[index] == ')')) {
163 177 *inhibitors = 0;
164 177 return 1;
165 }
166
2/2
✓ Branch 0 taken 44 times.
✓ Branch 1 taken 42699 times.
42743 if (*inhibitors == '\\') {
167 44 *inhibitors = 1;
168 44 return 0;
169 }
170
4/4
✓ Branch 0 taken 40929 times.
✓ Branch 1 taken 1770 times.
✓ Branch 3 taken 225 times.
✓ Branch 4 taken 40704 times.
42699 if (*inhibitors == 0 && my_char_is(command[index], "\'\"\\(")) {
171 225 *inhibitors = command[index];
172 225 return 1;
173 }
174 42474 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 1267 input_command_t *validate_input_command(input_command_t *input_command,
185 char inhibitors)
186 {
187
3/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1263 times.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
1267 if (inhibitors != 0 && inhibitors != 1) {
188 4 my_fprintf(2, "Unmatched '%c'.\n", inhibitors);
189 4 return NULL;
190 }
191 1263 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 1280 input_command_t *get_input_command(char *command)
200 {
201 1280 input_command_t *input_command = init_input_command(command);
202 1280 char inhibitors = 0;
203
204
6/6
✓ Branch 0 taken 241 times.
✓ Branch 1 taken 1293 times.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 1284 times.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 1280 times.
1534 while (command[0] == ' ' || command[0] == '\t' || command[0] == '\n')
205 254 command++;
206
2/2
✓ Branch 0 taken 42920 times.
✓ Branch 1 taken 1267 times.
44187 for (int index = 0; command[index] != '\0'; index++) {
207
2/2
✓ Branch 1 taken 402 times.
✓ Branch 2 taken 42518 times.
42920 if (update_inhibitors(command, index, &inhibitors)
208
2/2
✓ Branch 0 taken 87 times.
✓ Branch 1 taken 315 times.
402 && input_command->current != input_command->command)
209 87 continue;
210
2/2
✓ Branch 1 taken 13 times.
✓ Branch 2 taken 42820 times.
42833 if (check_error(input_command, command, index, inhibitors) == 1)
211 13 return NULL;
212
2/2
✓ Branch 1 taken 134 times.
✓ Branch 2 taken 42686 times.
42820 if (!add_char_to_input(input_command, command, &index, &inhibitors))
213 134 input_command->current = input_command->command;
214
2/2
✓ Branch 0 taken 44 times.
✓ Branch 1 taken 42776 times.
42820 if (inhibitors == 1)
215 44 inhibitors = 0;
216 }
217 1267 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