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 |