GCC Code Coverage Report


Directory: ./
File: src/parsing/replace_variable.c
Date: 2024-05-07 14:54:03
Exec Total Coverage
Lines: 79 95 83.2%
Functions: 8 8 100.0%
Branches: 46 64 71.9%

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 59 static char *find_valid_variable(char *line)
20 {
21
2/2
✓ Branch 1 taken 57 times.
✓ Branch 2 taken 2 times.
59 while (my_strstr(line, "$") != NULL) {
22
2/4
✓ Branch 1 taken 57 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 57 times.
114 if (*(my_strstr(line, "$") + 1) == '\0' ||
23 57 my_char_is(*(my_strstr(line, "$") + 1), " \t\n")) {
24 line = my_strstr(line, "$") + 1;
25 continue;
26 }
27 57 return my_strstr(line, "$");
28 }
29 2 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 9 static int display_error(char *variable, int type)
39 {
40
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 3 times.
9 if (type == 1) {
41 6 my_fprintf(2, "Illegal variable name.\n");
42 6 return -1;
43 }
44
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (type == 2) {
45 3 my_fprintf(2, "Missing '}'.\n");
46 3 return -1;
47 }
48 my_fprintf(2, "%s: Undefined variable.\n", variable);
49 FREE(variable);
50 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 4 static int get_variables_value(mysh_t *mysh, char *variable, char **value)
61 {
62 4 char *tmp = NULL;
63
64
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 for (node_t *node = mysh->variable_list; node; node = node->next) {
65
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 6 times.
10 if (my_strcmp(((variable_t *)node->data)->name, variable) == 0) {
66 4 *value = ((variable_t *)node->data)->value;
67 4 return 1;
68 }
69 }
70 tmp = get_env_var(mysh->env, variable);
71 if (tmp != NULL) {
72 *value = tmp;
73 return 1;
74 }
75 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 4 static char *get_new_line(char **line, char *value, int *nb_letters)
86 {
87 4 char *new_line = NULL;
88
89 4 new_line = calloc(find_valid_variable(*line) - *line +
90 4 my_strlen(value) + my_strlen(&((*line)[find_valid_variable(*line)
91 4 - *line + 1 + *nb_letters])) + 2, sizeof(char));
92 4 my_strncpy(new_line, *line,
93 4 find_valid_variable(*line) - *line);
94 4 my_strcat(new_line, value);
95 4 my_strcat(new_line, &((*line)[find_valid_variable(*line)
96 4 - *line + *nb_letters + 1]));
97 4 FREE(*line);
98 4 *nb_letters = 0;
99 4 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 4 char *clear_var(char *variable)
108 {
109 4 char *tmp = variable;
110
111
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
4 if (variable[0] && variable[0] == '{') {
112 tmp = my_strdup(&variable[1]);
113 FREE(variable);
114 }
115
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
4 if (tmp[my_strlen(tmp) - 1] == '}')
116 tmp[my_strlen(tmp) - 1] = '\0';
117 4 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 13 static int count_letter(char *line)
126 {
127 13 int nb_letters = 0;
128 13 int bracket = 0;
129 13 int index = find_valid_variable(line) - line + 1;
130
131
6/6
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 26 times.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 22 times.
✓ Branch 6 taken 11 times.
✓ Branch 7 taken 11 times.
76 for (; my_char_is_alpha(line[index]) || my_char_is_num(line[index]) ||
132 63 my_char_is(line[index], "_{}?"); index++) {
133 43 nb_letters++;
134
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 41 times.
43 if (line[index] == '}')
135 2 break;
136
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 32 times.
41 if (line[index] == '{')
137 9 bracket = 1;
138 }
139
5/6
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 4 times.
✓ Branch 5 taken 9 times.
✗ Branch 6 not taken.
13 if ((bracket && nb_letters < 2) || my_count_letter(line, '{') > 1
140
5/8
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 7 times.
9 || (line[index] == '}' && bracket && nb_letters == 2) ||
141 (nb_letters == 1 && line[index] == '}'))
142 6 return display_error(NULL, 1);
143
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
7 if (bracket && line[index] != '}')
144 3 return display_error(NULL, 2);
145 4 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 11 static int change_line(mysh_t *mysh, char **line)
155 {
156 11 char *variable = NULL;
157 11 int nb_letters = 0;
158 11 char *value = NULL;
159
160
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
11 if (find_valid_variable(*line) == NULL)
161 return 0;
162
2/2
✓ Branch 1 taken 13 times.
✓ Branch 2 taken 2 times.
15 while (find_valid_variable(*line) != NULL) {
163 13 nb_letters = count_letter(*line);
164
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 4 times.
13 if (nb_letters == -1)
165 9 return 1;
166 4 variable = clear_var(my_strndup(find_valid_variable(*line) + 1,
167 nb_letters));
168
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
4 if (get_variables_value(mysh, variable, &value) == 0)
169 return display_error(variable, 3);
170 4 FREE(variable);
171 4 *line = get_new_line(line, value, &nb_letters);
172 }
173 2 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 4783 int replace_variables(mysh_t *mysh)
182 {
183 4783 char *exit_status = NULL;
184
185
2/2
✓ Branch 1 taken 4772 times.
✓ Branch 2 taken 11 times.
4783 if (my_str_contains(mysh->line, "$") == 0)
186 4772 return 0;
187 11 exit_status = my_str_nbr(mysh->exit_status);
188 11 add_variable(mysh, "?", my_malloc_strdup(exit_status));
189 11 FREE(exit_status);
190
2/2
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 2 times.
11 if (change_line(mysh, &mysh->line)) {
191 9 mysh->exit_status = 1;
192 9 return 1;
193 }
194 2 return 0;
195 }
196