mirror of
https://codeberg.org/la-chouette/minishell.git
synced 2025-12-06 07:28:09 +01:00
Expansion: not dealing with potential directory yet
This commit is contained in:
parent
efae95950e
commit
1766e8d1ba
10 changed files with 192 additions and 25 deletions
12
src/env/env_manip.c
vendored
12
src/env/env_manip.c
vendored
|
|
@ -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));
|
||||||
|
|
|
||||||
|
|
@ -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
103
src/subst/path_split.c
Normal 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
32
src/subst/path_split.h
Normal 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
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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++;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue