Expansion: not dealing with potential directory yet

This commit is contained in:
Jérôme Guélen 2025-03-14 18:47:14 +01:00
parent efae95950e
commit 1766e8d1ba
No known key found for this signature in database
10 changed files with 192 additions and 25 deletions

12
src/env/env_manip.c vendored
View file

@ -3,10 +3,10 @@
/* ::: :::::::: */ /* ::: :::::::: */
/* env_manip.c :+: :+: :+: */ /* env_manip.c :+: :+: :+: */
/* +:+ +:+ +:+ */ /* +:+ +:+ +:+ */
/* By: jguelen <marvin@42.fr> +#+ +:+ +#+ */ /* By: jguelen <jguelen@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2025/02/12 18:29:12 by jguelen #+# #+# */ /* Created: 2025/02/12 18:29:12 by jguelen #+# #+# */
/* Updated: 2025/02/19 16:41:38 by khais ### ########.fr */ /* Updated: 2025/03/14 10:52:39 by jguelen ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -97,10 +97,10 @@ static void env_add_back(t_env **env, t_env *new)
** freed. In case a node matching the given key is found the provided key value ** freed. In case a node matching the given key is found the provided key value
** is freed. ** is freed.
** **
** If key or value are null, both are freed and NULL is returned. ft_errno is ** If key is null, both key and value are freed and NULL is returned. ft_errno
** set to FT_EINVAL. ** is set to FT_EINVAL. We therefore allow for a value to be NULL.
** **
** If key is an empty string, key and value is freed, ft_errno is set to ** If key is an empty string, key and value are freed, ft_errno is set to
** FT_EBADID, and NULL is returned. ** FT_EBADID, and NULL is returned.
** **
** If there is a failure allocating a new node, NULL is returned and ft_errno is ** If there is a failure allocating a new node, NULL is returned and ft_errno is
@ -116,7 +116,7 @@ t_env *env_set_entry(t_env **env, char *key, char *value)
{ {
t_env *node; t_env *node;
if (key == NULL || value == NULL) if (key == NULL)
return (ft_errno(FT_EINVAL), free2(key, value)); return (ft_errno(FT_EINVAL), free2(key, value));
if (*key == '\0') if (*key == '\0')
return (ft_errno(FT_EBADID), free2(key, value)); return (ft_errno(FT_EBADID), free2(key, value));

View file

@ -6,13 +6,17 @@
/* By: jguelen <jguelen@student.42.fr> +#+ +:+ +#+ */ /* By: jguelen <jguelen@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2025/02/19 18:21:55 by jguelen #+# #+# */ /* Created: 2025/02/19 18:21:55 by jguelen #+# #+# */
/* Updated: 2025/02/26 12:26:56 by jguelen ### ########.fr */ /* Updated: 2025/03/11 17:36:07 by jguelen ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
#ifndef SIG_H #ifndef SIG_H
# define SIG_H # define SIG_H
/*
** Needed to have the definitions relative to sigaction and siginfo
** correctly taken into account.
*/
# define _POSIX_C_SOURCE 200809L # define _POSIX_C_SOURCE 200809L
# include "libft.h" # include "libft.h"

103
src/subst/path_split.c Normal file
View file

@ -0,0 +1,103 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* path_split.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jguelen <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/03/14 10:07:47 by jguelen #+# #+# */
/* Updated: 2025/03/14 12:54:49 by jguelen ### ########.fr */
/* */
/* ************************************************************************** */
#include "path_split.h"
/*
** We do not ignore empty words here. The word count is therefore the number of
** times the separator appears + 1 or 0 if the string s is NULL.
*/
static size_t paths_count(const char *s, const char sep)
{
size_t count;
size_t i;
if (!s || !*s)
return (0);
i = 0;
count = 1;
while (s[i])
{
if (s[i] == sep)
count++;
i++;
}
return (count);
}
void path_split_destroy(char **split)
{
size_t i;
if (!split)
return ;
i = 0;
while (split[i])
free(split[i++]);
free(split);
}
/*
** Copies and returns in a malloc-allocated string the first "word" of *s.
** the first word is defined here as the longest substring of *s starting at
** the beginning of *s and not including any c character.
** During this process it moves *s past the next c character.
** NOTE: '\0' should never be considered a valid separator.
*/
static char *ft_dup_firstword(char **s, const char c)
{
char *first_word;
size_t i;
i = 0;
while ((*s)[i] && (*s)[i] != c)
i++;
first_word = malloc((i + 1) * sizeof(char));
ft_memmove(first_word, *s, i);
first_word[i] = '\0';
*s += i + 1;
return (first_word);
}
/*
** A modified version of a common word-split but that does not ignore NULL
** entries i.e. if PATH is of the form
** PATH=/usr/bin:::/bin
** the result will be {"/usr/bin", "", "", "/bin", NULL}
** where all elements except the terminating NULL has been malloc-allocated to
** ensure an ease of both treatment and end-detection.
** The parameter separator is maintained even if in our specific case it is
** expected to simply be ':'.
** @Retun Returns a NULL-terminated array when each entry correspond to a
** the longest substring possible between separator characters or end of string
** in the normal case. Returns NULL in case of an allocation error.
*/
char **path_split(char const *s, const char separator)
{
char **split;
size_t wc;
size_t i;
wc = paths_count(s, separator);
split = ft_calloc(wc + 1, sizeof(char *));
if (!split)
return (NULL);
i = 0;
while (i < wc)
{
split[i] = ft_dup_firstword((char **)&s, separator);
if (!split[i])
return (path_split_destroy(split), NULL);
i++;
}
return (split);
}

32
src/subst/path_split.h Normal file
View file

@ -0,0 +1,32 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* path_split.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jguelen <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/03/14 10:11:29 by jguelen #+# #+# */
/* Updated: 2025/03/14 12:20:27 by jguelen ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef PATH_SPLIT_H
# define PATH_SPLIT_H
# include <stdlib.h>
# include "libft.h"
/*
** A modified version of a common word-split but that does not ignore NULL
** entries i.e. if PATH is of the form
** PATH=/usr/bin:::/bin
** the resul will be {"/usr/bin", "", "", "/bin", NULL}
** where all elements except the terminating NULL has been malloc-allocated to
** ensure an ease of both treatment and end-detection.
** The parameter separator is maintained even if in our specific case it is
** expected to simply be ':'.
*/
char **path_split(const char *s, char separator);
void path_split_destroy(char **split);
#endif

View file

@ -6,7 +6,7 @@
/* By: jguelen <jguelen@student.42.fr> +#+ +:+ +#+ */ /* By: jguelen <jguelen@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2025/02/25 13:02:59 by jguelen #+# #+# */ /* Created: 2025/02/25 13:02:59 by jguelen #+# #+# */
/* Updated: 2025/03/10 18:30:20 by jguelen ### ########.fr */ /* Updated: 2025/03/14 09:55:09 by jguelen ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -27,11 +27,11 @@ char *replace_in_str(const char *text, size_t index_start, size_t index_end,
size_t len_rep; size_t len_rep;
size_t new_size; size_t new_size;
len_text = ft_strlen(text);
len_rep = ft_strlen(replacement);
new_size = len_text + index_start - index_end + len_rep;
if (index_end >= index_start) if (index_end >= index_start)
{ {
len_text = ft_strlen(text);
len_rep = ft_strlen(replacement);
new_size = len_text + index_start - index_end + len_rep;
new = malloc(new_size * sizeof(char)); new = malloc(new_size * sizeof(char));
if (!new) if (!new)
return (NULL); return (NULL);

View file

@ -6,14 +6,16 @@
/* 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/11 14:46:17 by jguelen ### ########.fr */ /* Updated: 2025/03/14 18:46:41 by jguelen ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
#include "minishell.h" #include "minishell.h"
#include "libft.h" #include "libft.h"
#include "../ft_errno.h" #include "../ft_errno.h"
#include "../env/env_manip.h"
#include <stdbool.h> #include <stdbool.h>
#include <sys/stat.h>
/* /*
** Returns a malloc-allocated string corresponding to ** Returns a malloc-allocated string corresponding to
@ -37,6 +39,11 @@ char *alloc_path(char *path_dir, char *name)
return (path); return (path);
} }
/*
** The return value of this function is always safe to destroy with
** path_split_destroy.
** Returns NULL in case of an allocation error.
*/
static char **get_paths_array(t_env *env) static char **get_paths_array(t_env *env)
{ {
char **path_array; char **path_array;
@ -44,29 +51,45 @@ static char **get_paths_array(t_env *env)
path_val = env_get_val(env, "PATH"); path_val = env_get_val(env, "PATH");
if (path_val == NULL) if (path_val == NULL)
{
path_array = ft_calloc(2, sizeof(char *));
if (!path_array)
return (NULL);
path_array[0] = ft_calloc(1, sizeof(char));
if (path_array[0] == NULL)
return (free(path_array), NULL);
return (path_array);
}
path_array = path_split(path_val, ':');
if (!path_array)
return (NULL); return (NULL);
path_array = minishell_split(path_val, ':');
return (path_array); return (path_array);
} }
/* /*
** TODO Check if filename refers to an actual file or a directory and what to ** TODO Do I need to preserve the entry if found to be a directory in case
** do about that case. ** there is no other later?
*/ */
char *filepath_from_env(char *filename, t_minishell *app) char *filepath_from_env(char *filename, t_minishell *app)
{ {
char *filepath; char *filepath;
char **path; char **path;
size_t i; size_t i;
struct stat file_stat;
path = get_paths_array(app->env); path = get_paths_array(app->env);
if (path == NULL) if (path == NULL)
return (NULL); return (NULL);
while (path[i]) while (path[i])
{ {
filepath = alloc_path(path[i], filename); if (!path[i][0])
if (access(filepath, F_OK) == 0) alloc_path(".", filename);
return (filepath); else
filepath = alloc_path(path[i], filename);
ret = stat(filepath, &file_stat); // Deal with possible failure of stat
if (access(filepath, F_OK) == 0 && ret == 0
&& S_ISREG(file_stat.st_mode))
return (destroy_split_array(path), filepath);
free(filepath); free(filepath);
i++; i++;
} }

View file

@ -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/07 17:26:31 by jguelen ### ########.fr */ /* Updated: 2025/03/14 14:28:20 by jguelen ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -14,6 +14,7 @@
# define SUBST_H # define SUBST_H
# include "../parser/wordlist/wordlist.h" # include "../parser/wordlist/wordlist.h"
# include "../parser/wordlist/wordlist_quicksort.h"
# include "../minishell.h" # include "../minishell.h"
# include <dirent.h> # include <dirent.h>
# include <unistd.h> # include <unistd.h>

View file

@ -6,7 +6,7 @@
/* By: jguelen <jguelen@student.42.fr> +#+ +:+ +#+ */ /* By: jguelen <jguelen@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2025/03/06 12:48:00 by khais #+# #+# */ /* Created: 2025/03/06 12:48:00 by khais #+# #+# */
/* Updated: 2025/03/10 14:11:30 by jguelen ### ########.fr */ /* Updated: 2025/03/14 09:56:51 by jguelen ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -79,6 +79,7 @@ static t_worddesc *word_update(t_worddesc *word, size_t i, size_t id_len,
/* /*
** Calculates the string corresponding to the value of the variable to be ** Calculates the string corresponding to the value of the variable to be
** expanded in the word proper and returns it. ** expanded in the word proper and returns it.
** The string returned is always malloc-allocated or NULL.
*/ */
static char *calculate_replacement(t_worddesc *word, t_minishell *app, size_t i, static char *calculate_replacement(t_worddesc *word, t_minishell *app, size_t i,
size_t *id_len) size_t *id_len)

View file

@ -6,12 +6,13 @@
/* By: jguelen <jguelen@student.42.fr> +#+ +:+ +#+ */ /* By: jguelen <jguelen@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2025/02/23 15:02:59 by jguelen #+# #+# */ /* Created: 2025/02/23 15:02:59 by jguelen #+# #+# */
/* Updated: 2025/03/10 17:21:25 by jguelen ### ########.fr */ /* Updated: 2025/03/14 14:30:30 by jguelen ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
#include "ft_printf.h" #include "ft_printf.h"
#include "subst.h" #include "subst.h"
#include "replace_substr.h"
/* /*
** TODO Pre-process file_pattern worddesc for a congruent marker string ** TODO Pre-process file_pattern worddesc for a congruent marker string

View file

@ -6,7 +6,7 @@
/* By: jguelen <jguelen@student.42.fr> +#+ +:+ +#+ */ /* By: jguelen <jguelen@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2025/03/07 17:10:01 by jguelen #+# #+# */ /* Created: 2025/03/07 17:10:01 by jguelen #+# #+# */
/* Updated: 2025/03/10 17:22:00 by jguelen ### ########.fr */ /* Updated: 2025/03/14 15:09:36 by jguelen ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -58,6 +58,8 @@ static int same_character_or_one_char_wild(char *str, t_worddesc *pattern,
** to be matched explicitely. We do however consider the case where the '.' ** to be matched explicitely. We do however consider the case where the '.'
** character cannot be matched unless explicitely when in first position ** character cannot be matched unless explicitely when in first position
** in str. ** in str.
** The algorithm is extremely similar to the one presented here:
** https://www.youtube.com/watch?v=3ZDZ-N0EPV0
*/ */
void build_pattern_checks(char *str, t_worddesc *pattern, void build_pattern_checks(char *str, t_worddesc *pattern,
char **pattern_check) char **pattern_check)