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 |