Expansion: A fix attempt

No time left to check before going home
This commit is contained in:
Jérôme Guélen 2025-03-18 18:55:25 +01:00
parent 35d391a813
commit bed41f4a6f
No known key found for this signature in database
6 changed files with 141 additions and 51 deletions

View file

@ -64,6 +64,7 @@ srcs = \
src/subst/path_split.c \
src/subst/replace_substr.c \
src/subst/simple_filename_exp.c \
src/subst/simple_filename_exp_utils.c \
src/subst/variable_subst.c \
src/subst/variable_subst_utils.c \
src/subst/wildcard_exp.c \

View file

@ -6,7 +6,7 @@
/* By: jguelen <jguelen@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/02/21 12:40:58 by khais #+# #+# */
/* Updated: 2025/03/21 10:13:38 by jguelen ### ########.fr */
/* Updated: 2025/03/21 10:14:26 by jguelen ### ########.fr */
/* */
/* ************************************************************************** */
@ -24,6 +24,7 @@ typedef enum e_errno
FT_EUNEXPECTED_PIPE,
FT_EMALFORMED_REDIRECTION,
FT_STATFAIL,
FT_ISDIR,
FT_EMAXERRNO,
} t_errno;

View file

@ -6,7 +6,7 @@
/* By: jguelen <jguelen@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/03/02 13:40:10 by jguelen #+# #+# */
/* Updated: 2025/03/18 12:37:03 by jguelen ### ########.fr */
/* Updated: 2025/03/18 18:38:53 by jguelen ### ########.fr */
/* */
/* ************************************************************************** */
@ -17,10 +17,6 @@
#include <stdbool.h>
#include <sys/stat.h>
/*
** TODO REMAKE the getting of path from env regarding the bash behaviors with a
** PATH variable with an empty value.
*/
/*
** Returns a malloc-allocated string corresponding to
** "path_dir/name"
@ -69,65 +65,88 @@ static char **get_paths_array(t_env *env)
return (path_array);
}
/*
** TODO Do I need to preserve the entry if found to be a directory in case
** there is no other later?
** Returns NULL on error or if nothing is found.
*/
char *filepath_from_env(char *filename, t_minishell *app)
static char *select_path(char *filepath, char **oldpath, char **path,
struct stat *fstat)
{
char *filepath;
char *oldpath;
char **path;
size_t i;
struct stat file_stat;
int ret;
ft_errno(FT_ESUCCESS);
ret = stat(filepath, fstat);
if (ret == -1)
return (destroy_split_array(path), ft_errno(FT_STATFAIL), NULL);
if (access(filepath, F_OK) == 0 && ret == 0 && S_ISREG(fstat->st_mode))
{
if (access(filepath, X_OK) != 0 && !oldpath)
*oldpath = filepath;
else
return (free(*oldpath), destroy_split_array(path), filepath);
}
if (*oldpath != filepath)
free(filepath);
return (NULL);
}
static char *deal_with_filled_path(char *filename, char **path,
struct stat *fstat)
{
size_t i;
char *oldpath;
char *filepath;
char *tmp;
path = get_paths_array(app->env);
if (path == NULL)
return (ft_errno(FT_ENOMEM), NULL);
i = 0;
oldpath = NULL;
if (!path[0])
{
ret = stat(filepath, &file_stat);
if (ret == -1)
return (ft_errno(FT_STATFAIL), NULL);
if (access(filepath, F_OK) == 0)
{
if (S_ISDIR(file_stat.st_mode) && !oldpath)
oldpath = filepath;
else if (S_ISREG(file_stat.st_mode))
return (alloc_path(".", filename));
}
}
while (path[i])
{
if (!path[i][0])
filepath = alloc_path(".", filename);
else
filepath = alloc_path(path[i], filename);
ret = stat(filepath, &file_stat);
if (ret == -1)
return (ft_errno(FT_STATFAIL), NULL);
if (access(filepath, F_OK) == 0 && ret == 0
&& S_ISREG(file_stat.st_mode))
{
if (access(filepath, X_OK) != 0)
{
if (!oldpath)
oldpath = filepath;
}
else
return (free(oldpath), destroy_split_array(path), filepath);
}
if (oldpath != filepath)
free(filepath);
if (!filepath)
return (ft_errno(FT_ENOMEM), NULL);
tmp = select_path(filepath, &oldpath, path, fstat);
if (tmp)
return (filepath);
else if (!tmp && ft_errno_get() == FT_STATFAIL)
return (NULL);
i++;
}
destroy_split_array(path);
return (oldpath);
}
/*
** Returns NULL on error or if nothing is found.
*/
char *filepath_from_env(char *filename, t_minishell *app)
{
char *filepath;
char **path;
struct stat fstat;
int ret;
path = get_paths_array(app->env);
if (path == NULL)
return (ft_errno(FT_ENOMEM), NULL);
if (!path[0])
{
filepath = alloc_path(".", filename);
if (!filepath)
return (ft_errno(FT_ENOMEM), NULL);
ret = stat(filepath, &fstat);
if (ret == -1)
return (ft_errno(FT_STATFAIL), free(filepath), NULL);
if (access(filepath, F_OK) == 0)
{
if (S_ISDIR(fstat.st_mode))
return (free(filepath), ft_errno(FT_ISDIR), NULL);
else if (S_ISREG(fstat.st_mode))
return (filepath);
}
}
return (deal_with_filled_path(filename, path, &fstat));
}
/*
** Returns a malloc-allocated string representing the full path to
** the command or executable corresponding to name or NULL in case of

View file

@ -0,0 +1,40 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* simple_filename_exp_utils.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jguelen <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/03/18 18:40:14 by jguelen #+# #+# */
/* Updated: 2025/03/18 18:40:33 by jguelen ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
#include "libft.h"
#include "../ft_errno.h"
#include "../env/env_manip.h"
#include <stdbool.h>
#include <sys/stat.h>
/*
** Returns a malloc-allocated string corresponding to
** "path_dir/name"
*/
char *alloc_path(char *path_dir, char *name)
{
char *path;
size_t dir_len;
size_t name_len;
dir_len = ft_strlen(path_dir);
name_len = ft_strlen(name);
path = malloc((dir_len + name_len + 2) * sizeof(char));
if (!path)
return (NULL);
ft_memcpy(path, path_dir, dir_len);
path[dir_len] = '/';
ft_memcpy(path + dir_len + 1, name, name_len);
path[dir_len + name_len + 1] = '\0';
return (path);
}

View file

@ -6,7 +6,7 @@
/* By: jguelen <jguelen@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/02/23 15:02:59 by jguelen #+# #+# */
/* Updated: 2025/03/15 14:45:11 by jguelen ### ########.fr */
/* Updated: 2025/03/18 18:44:05 by jguelen ### ########.fr */
/* */
/* ************************************************************************** */
@ -178,6 +178,7 @@ t_wordlist *expand_star(t_worddesc *file_pattern)
char *tmp;
i = 0;
clean_pattern(file_pattern);
while (file_pattern->word[i])
{
if (file_pattern->marker[i] != '\'' && file_pattern->marker[i] != '"'

View file

@ -6,11 +6,39 @@
/* By: jguelen <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/03/15 15:09:56 by jguelen #+# #+# */
/* Updated: 2025/03/15 15:10:30 by jguelen ### ########.fr */
/* Updated: 2025/03/18 18:54:06 by jguelen ### ########.fr */
/* */
/* ************************************************************************** */
#include "subst.h"
#include "replace_substr.h"
/*
** TODO
*/
void clean_pattern(t_worddesc *file_pattern)
{
int i;
char *tmp;
i = 0;
while (file_pattern->word[i])
{
if ((file_pattern->word[i] == '"' || file_pattern->word[i] == '\'')
&& file_pattern->marker[i] != '&' && file_pattern->marker[i] != '"'
&& file_pattern->marker[i] != '\'')
{
tmp = replace_in_str(file_pattern->word, i, i, "");
free(file_pattern->word);
file_pattern->word = tmp;
tmp = replace_in_str(file_pattern->marker, i, i, "");
free(file_pattern->marker);
file_pattern->marker = tmp;
continue ;
}
i++;
}
}
/*
** Checks if a worddesc is to be considered a pattern as bash would in a