GCC Code Coverage Report


Directory: ./
File: src/builtins/foreach.c
Date: 2024-06-05 00:36:48
Exec Total Coverage
Lines: 9 71 12.7%
Functions: 2 5 40.0%
Branches: 2 46 4.3%

Line Branch Exec Source
1 /*
2 ** EPITECH PROJECT, 2024
3 ** 42sh
4 ** File description:
5 ** The file containing the foreach builtin
6 */
7 /**
8 * @file foreach.c
9 * @brief The file containing the foreach builtin
10 */
11
12 #include "../../include/myshell.h"
13
14 /**
15 * @brief Get the content of the variable
16 * @param mysh The shell structure
17 * @return <b>char **</b> The content of the variable
18 */
19 char **get_variable_content(mysh_t *mysh)
20 {
21 char *variables = NULL;
22 char **variable_content = NULL;
23 int size = 0;
24
25 for (int index = 2; mysh->args[index] != NULL; index++)
26 size += my_strlen(mysh->args[index]);
27 variables = calloc(size, sizeof(char));
28 my_strcpy(variables, mysh->args[2] + 1);
29 for (int index = 3; mysh->args[index] != NULL; index++) {
30 my_strcat(variables, mysh->args[index]);
31 if (mysh->args[index + 1] != NULL)
32 my_strcat(variables, " ");
33 }
34 variables[my_strlen(variables) - 1] = '\0';
35 variable_content = STR2ARRAY_SEP(variables, " \t\n");
36 free(variables);
37 return variable_content;
38 }
39
40 /**
41 * @brief Check if the foreach command is valid
42 * @param mysh The shell structure
43 * @return <b>int</b> <u>0</u> if the variable is valid, <u>1</u> otherwise
44 */
45 3 static int error_handling(mysh_t *mysh)
46 {
47
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3 if (mysh->args[1] == NULL || mysh->args[2] == NULL) {
48 3 my_putstr_error("foreach: Too few arguments.\n");
49 3 return 1;
50 }
51 if (is_valid_variable(mysh->args[1], "foreach") == 0)
52 return 1;
53 for (int index = 2; mysh->args[index] != NULL; index++) {
54 if (my_str_contains(mysh->args[index], "(") == 0
55 || my_str_contains(mysh->args[index], ")") == 0) {
56 my_putstr_error("foreach: Words not parenthesized.\n");
57 return 1;
58 }
59 }
60 return 0;
61 }
62
63 /**
64 * @brief Read the content of the foreach
65 * @param mysh The shell structure
66 * @param command_list The list of commands
67 * @return <b>int</b> <u>0</u> if the command succeed, <u>1</u> otherwise
68 */
69 static int read_input(mysh_t *mysh, node_t **command_list)
70 {
71 int size = 0;
72 char *line = NULL;
73 char **content = NULL;
74
75 while (size != EOF && (content == NULL || my_strcmp(content[0], "end"))) {
76 IS_ATTY_PRINT("foreach? ");
77 free_str_and_tab(line, NULL);
78 size = my_getline(&line, stdin);
79 set_command_in_history(mysh, line);
80 free_str_and_tab(NULL, content);
81 content = str_to_array_inhibitors(line);
82 if (line != NULL)
83 my_push_back(command_list, my_strdup(line), STRING);
84 }
85 if (size == EOF || (content != NULL && my_strcmp(content[0], "end"))) {
86 free_str_and_tab(line, content);
87 return 1;
88 }
89 free_str_and_tab(line, content);
90 return 0;
91 }
92
93 /**
94 * @brief Execute the command
95 * @param mysh The shell structure
96 * @param command The command to execute
97 * @return <b>void</b>
98 */
99 void execute_command(mysh_t *mysh, char *command)
100 {
101 pid_t pid = fork();
102
103 if (pid == 0) {
104 analyse_backticks(mysh, command);
105 my_exit(mysh, mysh->exit_status, NULL);
106 } else
107 waitpid(pid, &mysh->exit_status, 0);
108 }
109
110 /**
111 * @brief The foreach builtin
112 * @param mysh The shell structure
113 * @return <b>int</b> <u>0</u> if the command succeed, <u>1</u> otherwise
114 */
115 3 int exec_foreach(mysh_t *mysh)
116 {
117 3 char **variable_content = NULL;
118 3 node_t *command_list = NULL;
119
120
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 if (error_handling(mysh))
121 3 return 1;
122 variable_content = get_variable_content(mysh);
123 if (read_input(mysh, &command_list)) {
124 my_putstr_error("foreach: end not found.\n");
125 FREE_WORD_ARRAY(variable_content);
126 my_delete_list(&command_list);
127 return 1;
128 }
129 for (int index = 0; variable_content[index] != NULL; index++) {
130 add_variable(mysh, mysh->args[1], variable_content[index]);
131 for (node_t *tmp = command_list; tmp && tmp->next; tmp = tmp->next)
132 execute_command(mysh, (char *)tmp->data);
133 }
134 FREE_WORD_ARRAY(variable_content);
135 my_delete_list(&command_list);
136 return 0;
137 }
138