mirror of
https://codeberg.org/la-chouette/minishell.git
synced 2025-12-06 07:28:09 +01:00
Expansion: Most changes dealt with
This commit is contained in:
parent
532d71efb0
commit
2a61706f1a
6 changed files with 64 additions and 35 deletions
10
src/env/env_manip.c
vendored
10
src/env/env_manip.c
vendored
|
|
@ -3,10 +3,10 @@
|
||||||
/* ::: :::::::: */
|
/* ::: :::::::: */
|
||||||
/* env_manip.c :+: :+: :+: */
|
/* env_manip.c :+: :+: :+: */
|
||||||
/* +:+ +:+ +:+ */
|
/* +:+ +:+ +:+ */
|
||||||
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
|
/* By: jguelen <jguelen@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/03/19 17:55/24 by khais #+# #+# */
|
/* Created: 2025/03/19 17:55:24 by khais #+# #+# */
|
||||||
/* Updated: 2025/03/19 17:55:24 by khais ### ########.fr */
|
/* Updated: 2025/03/21 18:49:56 by jguelen ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
|
@ -49,7 +49,7 @@ void env_rm_entry(t_env **env, char *key)
|
||||||
|
|
||||||
if (env == NULL || (*env) == NULL)
|
if (env == NULL || (*env) == NULL)
|
||||||
return ;
|
return ;
|
||||||
if (strncmp((*env)->key, key, INT_MAX) == 0)
|
if (ft_strncmp((*env)->key, key, INT_MAX) == 0)
|
||||||
{
|
{
|
||||||
next = (*env)->next;
|
next = (*env)->next;
|
||||||
env_destroy_node(*env);
|
env_destroy_node(*env);
|
||||||
|
|
@ -59,7 +59,7 @@ void env_rm_entry(t_env **env, char *key)
|
||||||
current = *env;
|
current = *env;
|
||||||
while (current->next)
|
while (current->next)
|
||||||
{
|
{
|
||||||
if (strncmp(current->next->key, key, INT_MAX) == 0)
|
if (ft_strncmp(current->next->key, key, INT_MAX) == 0)
|
||||||
{
|
{
|
||||||
next = current->next;
|
next = current->next;
|
||||||
current->next = next->next;
|
current->next = next->next;
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
|
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/02/21 12:40:46 by khais #+# #+# */
|
/* Created: 2025/02/21 12:40:46 by khais #+# #+# */
|
||||||
/* Updated: 2025/03/10 16:56:52 by khais ### ########.fr */
|
/* Updated: 2025/03/21 16:18:57 by jguelen ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
|
@ -53,6 +53,9 @@ char *ft_strerror(t_errno errno)
|
||||||
[FT_EUNEXPECTED_PIPE] = "minishell: syntax error near unexpected token `|'",
|
[FT_EUNEXPECTED_PIPE] = "minishell: syntax error near unexpected token `|'",
|
||||||
[FT_EMALFORMED_REDIRECTION] = "minishell: malformed redirection (perhaps a \
|
[FT_EMALFORMED_REDIRECTION] = "minishell: malformed redirection (perhaps a \
|
||||||
missing filename)",
|
missing filename)",
|
||||||
|
[FT_ENOMEM] = "Cannot allocate memory",
|
||||||
|
[FT_STATFAIL] = "minishell: stat: internal failure",
|
||||||
|
[FT_ISDIR] = "Is a directory",
|
||||||
};
|
};
|
||||||
|
|
||||||
if (errno >= 0 && errno < FT_EMAXERRNO)
|
if (errno >= 0 && errno < FT_EMAXERRNO)
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
/* By: jguelen <jguelen@student.42.fr> +#+ +:+ +#+ */
|
/* By: jguelen <jguelen@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/03/02 13:40:10 by jguelen #+# #+# */
|
/* Created: 2025/03/02 13:40:10 by jguelen #+# #+# */
|
||||||
/* Updated: 2025/03/19 16:46:55 by jguelen ### ########.fr */
|
/* Updated: 2025/03/21 17:33:50 by jguelen ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
|
@ -45,6 +45,17 @@ static char **get_paths_array(t_env *env)
|
||||||
return (path_array);
|
return (path_array);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Utility function that attempts to find a regular executable file for which
|
||||||
|
** the execution rights are granted. It disregards non-regular files and so in
|
||||||
|
** particular directories (note that using stat allows us to follow symlinks to
|
||||||
|
** their target if encountered). If a file is found here for which the execution
|
||||||
|
** permission is not granted and no elligible file was found before its path is
|
||||||
|
** stored inside oldpath so that in case no file is found to be executable it
|
||||||
|
** is the value stored in oldpath that will be used resulting in a Permission
|
||||||
|
** denied error. oldpath is to store the first occurrence of a regular file
|
||||||
|
** corresponding to the filepath but not executable.
|
||||||
|
*/
|
||||||
static char *select_path(char *filepath, char **oldpath, char **path,
|
static char *select_path(char *filepath, char **oldpath, char **path,
|
||||||
struct stat *fstat)
|
struct stat *fstat)
|
||||||
{
|
{
|
||||||
|
|
@ -58,7 +69,7 @@ static char *select_path(char *filepath, char **oldpath, char **path,
|
||||||
{
|
{
|
||||||
if (access(filepath, X_OK) != 0)
|
if (access(filepath, X_OK) != 0)
|
||||||
{
|
{
|
||||||
if (!oldpath)
|
if (!(*oldpath))
|
||||||
*oldpath = filepath;
|
*oldpath = filepath;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -70,6 +81,14 @@ static char *select_path(char *filepath, char **oldpath, char **path,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
** This function exists to implement the bash behaviour specific to where
|
||||||
|
** the PATH variable has been set with a non-empty value.
|
||||||
|
** It checks the working directory if there is a void inside PATH and tries to
|
||||||
|
** find the executable command inside the path entry itself otherwise
|
||||||
|
** disregarding directories and selecting the first entry that both exists and
|
||||||
|
** is executable. If no such entry exists but one or more regular file(s)
|
||||||
|
** exist(s) with the correct name in one of the entries (it therefore lacks the
|
||||||
|
** execution permission) this function will return the first found.
|
||||||
** Returns NULL if an error occurred or nothing corresponds to filename
|
** Returns NULL if an error occurred or nothing corresponds to filename
|
||||||
** in PATH. ft_errno is set in the course of this function to help distinguish
|
** in PATH. ft_errno is set in the course of this function to help distinguish
|
||||||
** the nature of the case.
|
** the nature of the case.
|
||||||
|
|
@ -104,6 +123,16 @@ static char *deal_with_filled_path(char *filename, char **path,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
** This function searches the environment to resolve a full path for an
|
||||||
|
** executable file corresponding to filename. It deals with two types of bash
|
||||||
|
** behaviours: a PATH unset or corresponding to an empty value and a PATH set
|
||||||
|
** and with a non-empty value.
|
||||||
|
** In the first case it searches the current working directory for the file
|
||||||
|
** coorresponding to filename. If no regular file is found it returns NULL and
|
||||||
|
** distinguishes the case where a directory was found corresponding to filename
|
||||||
|
** by setting ft_errno to FT_ISDIR.
|
||||||
|
** The second case is dealt with using deal_with_filled_path (see the function
|
||||||
|
** itself for details).
|
||||||
** Returns NULL on error or if nothing is found.
|
** Returns NULL on error or if nothing is found.
|
||||||
*/
|
*/
|
||||||
static char *filepath_from_env(char *filename, t_minishell *app)
|
static char *filepath_from_env(char *filename, t_minishell *app)
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
/* By: jguelen <jguelen@student.42.fr> +#+ +:+ +#+ */
|
/* By: jguelen <jguelen@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/02/23 15:01:40 by jguelen #+# #+# */
|
/* Created: 2025/02/23 15:01:40 by jguelen #+# #+# */
|
||||||
/* Updated: 2025/03/19 09:20:02 by jguelen ### ########.fr */
|
/* Updated: 2025/03/21 18:47:30 by jguelen ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
|
@ -42,5 +42,6 @@ char *get_cmdpath(const char *name, t_minishell *app);
|
||||||
void destroy_pattern_check(char **pattern_check, size_t len);
|
void destroy_pattern_check(char **pattern_check, size_t len);
|
||||||
void build_pattern_checks(char *str, t_worddesc *pattern,
|
void build_pattern_checks(char *str, t_worddesc *pattern,
|
||||||
char **checker);
|
char **checker);
|
||||||
|
void clean_pattern(t_worddesc *file_pattern);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
|
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/03/19 17:28/29 by khais #+# #+# */
|
/* Created: 2025/03/19 17:28/29 by khais #+# #+# */
|
||||||
/* Updated: 2025/03/19 17:28:29 by khais ### ########.fr */
|
/* Updated: 2025/03/21 17:38:16 by jguelen ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
|
@ -101,9 +101,9 @@ static char *calculate_replacement(t_worddesc *word, t_minishell *app, size_t i,
|
||||||
{
|
{
|
||||||
rep = env_get_val(app->env, id);
|
rep = env_get_val(app->env, id);
|
||||||
if (!rep)
|
if (!rep)
|
||||||
rep = strdup("");
|
rep = ft_strdup("");
|
||||||
else
|
else
|
||||||
rep = strdup(rep);
|
rep = ft_strdup(rep);
|
||||||
if (!rep)
|
if (!rep)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
/* By: jguelen <jguelen@student.42.fr> +#+ +:+ +#+ */
|
/* By: jguelen <jguelen@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/03/20 15:01:38 by jguelen #+# #+# */
|
/* Created: 2025/03/20 15:01:38 by jguelen #+# #+# */
|
||||||
/* Updated: 2025/03/20 16:53:31 by jguelen ### ########.fr */
|
/* Updated: 2025/03/21 18:42:04 by jguelen ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
|
@ -50,18 +50,30 @@ static DIR *open_current_dir(void)
|
||||||
return (dir);
|
return (dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Adds filename to the end of the wordlist *list by creating a worddesc whose
|
||||||
|
** word is filename and marker makes filename be considered fully single
|
||||||
|
** quoted.
|
||||||
|
** NOTE: In case of error, this function destroys *list in a similar fashion
|
||||||
|
** as worddesc_create destroys its first parameter in case of failure.
|
||||||
|
*/
|
||||||
static t_wordlist *add_file_to_list(t_wordlist **list, char *filename)
|
static t_wordlist *add_file_to_list(t_wordlist **list, char *filename)
|
||||||
{
|
{
|
||||||
t_worddesc *file_desc;
|
t_worddesc *file_desc;
|
||||||
char *copy;
|
char *copy;
|
||||||
|
char *marker;
|
||||||
|
|
||||||
copy = ft_strdup(filename);
|
copy = ft_strdup(filename);
|
||||||
if (!copy)
|
if (!copy)
|
||||||
return (wordlist_destroy(*list), NULL);
|
return (wordlist_destroy(*list), NULL);
|
||||||
file_desc = worddesc_create(copy, '\0', NULL);
|
marker = construct_repeting_char_string('\'', ft_strlen(copy));
|
||||||
|
if (!marker)
|
||||||
|
return (wordlist_destroy(*list), free(copy), NULL);
|
||||||
|
file_desc = worddesc_create(copy, '\0', marker);
|
||||||
if (!file_desc)
|
if (!file_desc)
|
||||||
{
|
{
|
||||||
wordlist_destroy(*list);
|
wordlist_destroy(*list);
|
||||||
|
free(marker);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
*list = wordlist_push(*list, file_desc);
|
*list = wordlist_push(*list, file_desc);
|
||||||
|
|
@ -117,7 +129,10 @@ static t_wordlist *expand_star_core(t_worddesc *file_pattern)
|
||||||
** Takes only into account the * wildcard or ?, those characters
|
** Takes only into account the * wildcard or ?, those characters
|
||||||
** NOTE: for a pattern to accept '.' as the first character of a filename
|
** NOTE: for a pattern to accept '.' as the first character of a filename
|
||||||
** it must be explicitly matched (only for the first character though).
|
** it must be explicitly matched (only for the first character though).
|
||||||
** Similarly, '/' is never to be matched except if given explicitly.
|
** Similarly, '/' is never to be matched except if given explicitly as per
|
||||||
|
** bash requirement. This is a note in case of future expansion as in our case
|
||||||
|
** here we do not have to deal with that since we concern ourselves only with
|
||||||
|
** the current working directory.
|
||||||
*/
|
*/
|
||||||
char fits_pattern(char *str, t_worddesc *pattern)
|
char fits_pattern(char *str, t_worddesc *pattern)
|
||||||
{
|
{
|
||||||
|
|
@ -156,25 +171,6 @@ char fits_pattern(char *str, t_worddesc *pattern)
|
||||||
*/
|
*/
|
||||||
t_wordlist *expand_star(t_worddesc *file_pattern)
|
t_wordlist *expand_star(t_worddesc *file_pattern)
|
||||||
{
|
{
|
||||||
size_t i;
|
clean_pattern(file_pattern);
|
||||||
char *tmp;
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
while (file_pattern->word[i])
|
|
||||||
{
|
|
||||||
if (file_pattern->marker[i] != '\'' && file_pattern->marker[i] != '"'
|
|
||||||
&& file_pattern->marker[i] != '&' && file_pattern->marker[i] != '$'
|
|
||||||
&& (file_pattern->word[i] == '\'' || file_pattern->word[i] == '"'))
|
|
||||||
{
|
|
||||||
tmp = replace_in_str(file_pattern->word, i, i, NULL);
|
|
||||||
free(file_pattern->word);
|
|
||||||
file_pattern->word = tmp;
|
|
||||||
tmp = replace_in_str(file_pattern->marker, i, i, NULL);
|
|
||||||
free(file_pattern->marker);
|
|
||||||
file_pattern->marker = tmp;
|
|
||||||
continue ;
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
return (expand_star_core(file_pattern));
|
return (expand_star_core(file_pattern));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue