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 :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jguelen <marvin@42.fr> +#+ +:+ +#+ */
/* By: jguelen <jguelen@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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
** is freed.
**
** If key or value are null, both are freed and NULL is returned. ft_errno is
** set to FT_EINVAL.
** If key is null, both key and value are freed and NULL is returned. ft_errno
** 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.
**
** 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;
if (key == NULL || value == NULL)
if (key == NULL)
return (ft_errno(FT_EINVAL), free2(key, value));
if (*key == '\0')
return (ft_errno(FT_EBADID), free2(key, value));

View file

@ -6,13 +6,17 @@
/* By: jguelen <jguelen@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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
# define SIG_H
/*
** Needed to have the definitions relative to sigaction and siginfo
** correctly taken into account.
*/
# define _POSIX_C_SOURCE 200809L
# 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> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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 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)
{
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));
if (!new)
return (NULL);

View file

@ -6,14 +6,16 @@
/* By: jguelen <jguelen@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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 "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
@ -37,6 +39,11 @@ char *alloc_path(char *path_dir, char *name)
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)
{
char **path_array;
@ -44,29 +51,45 @@ static char **get_paths_array(t_env *env)
path_val = env_get_val(env, "PATH");
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);
path_array = minishell_split(path_val, ':');
return (path_array);
}
/*
** TODO Check if filename refers to an actual file or a directory and what to
** do about that case.
** TODO Do I need to preserve the entry if found to be a directory in case
** there is no other later?
*/
char *filepath_from_env(char *filename, t_minishell *app)
{
char *filepath;
char **path;
size_t i;
char *filepath;
char **path;
size_t i;
struct stat file_stat;
path = get_paths_array(app->env);
if (path == NULL)
return (NULL);
while (path[i])
{
filepath = alloc_path(path[i], filename);
if (access(filepath, F_OK) == 0)
return (filepath);
if (!path[i][0])
alloc_path(".", filename);
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);
i++;
}

View file

@ -6,7 +6,7 @@
/* By: jguelen <jguelen@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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
# include "../parser/wordlist/wordlist.h"
# include "../parser/wordlist/wordlist_quicksort.h"
# include "../minishell.h"
# include <dirent.h>
# include <unistd.h>

View file

@ -6,7 +6,7 @@
/* By: jguelen <jguelen@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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
** 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,
size_t *id_len)

View file

@ -6,12 +6,13 @@
/* By: jguelen <jguelen@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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 "subst.h"
#include "replace_substr.h"
/*
** TODO Pre-process file_pattern worddesc for a congruent marker string

View file

@ -6,7 +6,7 @@
/* By: jguelen <jguelen@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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 '.'
** character cannot be matched unless explicitely when in first position
** 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,
char **pattern_check)