| 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 |