GCC Code Coverage Report


Directory: ./
File: src/parsing/replace_variable.c
Date: 2024-06-05 00:36:48
Exec Total Coverage
Lines: 90 95 94.7%
Functions: 8 8 100.0%
Branches: 57 64 89.1%

Line Branch Exec Source
1 /*
2 ** EPITECH PROJECT, 2024
3 ** 42sh
4 ** File description:
5 ** The file containing the replace_variable functions
6 */
7 /**
8 * @file replace_variable.c
9 * @brief The file containing the replace_variable functions
10 */
11
12 #include "../../include/myshell.h"
13
14 /**
15 * @brief Find the first valid variable in a string
16 * @param line The string
17 * @return <b>char *</b> The variable
18 */
19 148 static char *find_valid_variable(char *line)
20 {
21
2/2
✓ Branch 1 taken 139 times.
✓ Branch 2 taken 9 times.
148 while (my_strstr(line, "$") != NULL) {
22
2/4
✓ Branch 1 taken 139 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 139 times.
278 if (*(my_strstr(line, "$") + 1) == '\0' ||
23 139 my_char_is(*(my_strstr(line, "$") + 1), " \t\n")) {
24 line = my_strstr(line, "$") + 1;
25 continue;
26 }
27 139 return my_strstr(line, "$");
28 }
29 9 return NULL;
30 }
31
32 /**
33 * @brief Display an error message
34 * @param variable The variable
35 * @param type The type of error
36 * @return <b>int</b> The exit status
37 */
38 13 static int display_error(char *variable, int type)
39 {
40
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 8 times.
13 if (type == 1) {
41 5 my_fprintf(2, "Illegal variable name.\n");
42 5 return -1;
43 }
44
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 7 times.
8 if (type == 2) {
45 1 my_fprintf(2, "Missing '}'.\n");
46 1 return -1;
47 }
48 7 my_fprintf(2, "%s: Undefined variable.\n", variable);
49 7 FREE(variable);
50 7 return 1;
51 }
52
53 /**
54 * @brief Get the value of a variable
55 * @param mysh The shell structure
56 * @param variable The variable
57 * @param value The value
58 * @return <b>int</b> The exit status
59 */
60 19 static int get_variables_value(mysh_t *mysh, char *variable, char **value)
61 {
62 19 char *tmp = NULL;
63
64
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 7 times.
35 for (node_t *node = mysh->variable_list; node; node = node->next) {
65
2/2
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 16 times.
28 if (my_strcmp(((variable_t *)node->data)->name, variable) == 0) {
66 12 *value = ((variable_t *)node->data)->value;
67 12 return 1;
68 }
69 }
70 7 tmp = get_env_var(mysh->env, variable);
71
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (tmp != NULL) {
72 *value = tmp;
73 return 1;
74 }
75 7 return 0;
76 }
77
78 /**
79 * @brief Get the new line
80 * @param line The line
81 * @param value The value
82 * @param nb_letters The number of letters
83 * @return <b>char *</b> The new line
84 */
85 12 static char *get_new_line(char **line, char *value, int *nb_letters)
86 {
87 12 char *new_line = NULL;
88
89 12 new_line = calloc(find_valid_variable(*line) - *line +
90 12 my_strlen(value) + my_strlen(&((*line)[find_valid_variable(*line)
91 12 - *line + 1 + *nb_letters])) + 2, sizeof(char));
92 12 my_strncpy(new_line, *line,
93 12 find_valid_variable(*line) - *line);
94 12 my_strcat(new_line, value);
95 12 my_strcat(new_line, &((*line)[find_valid_variable(*line)
96 12 - *line + *nb_letters + 1]));
97 12 FREE(*line);
98 12 *nb_letters = 0;
99 12 return new_line;
100 }
101
102 /**
103 * @brief Clear the variable
104 * @param variable The variable
105 * @return <b>char *</b> The cleared variable
106 */
107 19 char *clear_var(char *variable)
108 {
109 19 char *tmp = variable;
110
111
3/4
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 15 times.
19 if (variable[0] && variable[0] == '{') {
112 4 tmp = my_strdup(&variable[1]);
113 4 FREE(variable);
114 }
115
2/2
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 14 times.
19 if (tmp[my_strlen(tmp) - 1] == '}')
116 5 tmp[my_strlen(tmp) - 1] = '\0';
117 19 return tmp;
118 }
119
120 /**
121 * @brief Count the number of letters in a variable
122 * @param line The line
123 * @return <b>int</b> The number of letters
124 */
125 25 static int count_letter(char *line)
126 {
127 25 int nb_letters = 0;
128 25 int bracket = 0;
129 25 int index = find_valid_variable(line) - line + 1;
130
131
6/6
✓ Branch 1 taken 53 times.
✓ Branch 2 taken 45 times.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 39 times.
✓ Branch 6 taken 21 times.
✓ Branch 7 taken 18 times.
137 for (; my_char_is_alpha(line[index]) || my_char_is_num(line[index]) ||
132 112 my_char_is(line[index], "_{}?"); index++) {
133 80 nb_letters++;
134
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 73 times.
80 if (line[index] == '}')
135 7 break;
136
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 65 times.
73 if (line[index] == '{')
137 8 bracket = 1;
138 }
139
5/6
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 17 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 3 times.
✓ Branch 5 taken 22 times.
✗ Branch 6 not taken.
25 if ((bracket && nb_letters < 2) || my_count_letter(line, '{') > 1
140
7/8
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 15 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 9 times.
✓ Branch 7 taken 13 times.
22 || (line[index] == '}' && bracket && nb_letters == 2) ||
141
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 7 times.
9 (nb_letters == 1 && line[index] == '}'))
142 5 return display_error(NULL, 1);
143
4/4
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 15 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 4 times.
20 if (bracket && line[index] != '}')
144 1 return display_error(NULL, 2);
145 19 return nb_letters;
146 }
147
148 /**
149 * @brief Change the line
150 * @param mysh The shell structure
151 * @param line The line
152 * @return <b>int</b> The exit status
153 */
154 22 static int change_line(mysh_t *mysh, char **line)
155 {
156 22 char *variable = NULL;
157 22 int nb_letters = 0;
158 22 char *value = NULL;
159
160
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 22 times.
22 if (find_valid_variable(*line) == NULL)
161 return 0;
162
2/2
✓ Branch 1 taken 25 times.
✓ Branch 2 taken 9 times.
34 while (find_valid_variable(*line) != NULL) {
163 25 nb_letters = count_letter(*line);
164
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 19 times.
25 if (nb_letters == -1)
165 6 return 1;
166 19 variable = clear_var(my_strndup(find_valid_variable(*line) + 1,
167 nb_letters));
168
2/2
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 12 times.
19 if (get_variables_value(mysh, variable, &value) == 0)
169 7 return display_error(variable, 3);
170 12 FREE(variable);
171 12 *line = get_new_line(line, value, &nb_letters);
172 }
173 9 return 0;
174 }
175
176 /**
177 * @brief Replace the variables in the command arguments
178 * @param mysh The shell structure
179 * @return <b>int/b> The new command arguments
180 */
181 4712 int replace_variables(mysh_t *mysh)
182 {
183 4712 char *exit_status = NULL;
184
185
2/2
✓ Branch 1 taken 4690 times.
✓ Branch 2 taken 22 times.
4712 if (my_str_contains(mysh->line, "$") == 0)
186 4690 return 0;
187 22 exit_status = my_str_nbr(mysh->exit_status);
188 22 add_variable(mysh, "?", my_malloc_strdup(exit_status));
189 22 FREE(exit_status);
190
2/2
✓ Branch 1 taken 13 times.
✓ Branch 2 taken 9 times.
22 if (change_line(mysh, &mysh->line)) {
191 13 mysh->exit_status = 1;
192 13 return 1;
193 }
194 9 return 0;
195 }
196