mirror of
https://codeberg.org/la-chouette/minishell.git
synced 2025-12-06 07:28:09 +01:00
Expansion: refactor in progress
This commit is contained in:
parent
ce24304e34
commit
95d9f6282a
11 changed files with 270 additions and 47 deletions
24
src/parser/wordlist/wordlist_quicksort.c
Normal file
24
src/parser/wordlist/wordlist_quicksort.c
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* wordlist_quicksort.c :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: jguelen <marvin@42.fr> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2025/03/08 17:29:05 by jguelen #+# #+# */
|
||||||
|
/* Updated: 2025/03/08 17:31:56 by jguelen ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#include "wordlist_quicksort.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
** TODO
|
||||||
|
** Returns the wordlist list sorted in ascending ascii order.
|
||||||
|
** Proceeds by directly swapping the inside contents and not by rewiring the
|
||||||
|
** nodes themselves.
|
||||||
|
*/
|
||||||
|
t_wordlist *wordlist_quicksort(t_wordlist *list)
|
||||||
|
{
|
||||||
|
return (list);
|
||||||
|
}
|
||||||
20
src/parser/wordlist/wordlist_quicksort.h
Normal file
20
src/parser/wordlist/wordlist_quicksort.h
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* wordlist_quicksort.h :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: jguelen <marvin@42.fr> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2025/03/08 17:26:52 by jguelen #+# #+# */
|
||||||
|
/* Updated: 2025/03/08 17:28:59 by jguelen ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#ifndef WORDLIST_QUICKSORT_H
|
||||||
|
# define WORDLIST_QUICKSORT_H
|
||||||
|
|
||||||
|
# include "wordlist.h"
|
||||||
|
|
||||||
|
t_wordlist *wordlist_quicksort(t_wordlist *list);
|
||||||
|
|
||||||
|
#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/02/26 13:30:07 by jguelen ### ########.fr */
|
/* Updated: 2025/03/08 14:52:42 by jguelen ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
|
@ -20,7 +20,7 @@
|
||||||
** Returns NULL if an allocation error occurred.
|
** Returns NULL if an allocation error occurred.
|
||||||
*/
|
*/
|
||||||
char *replace_in_str(const char *text, size_t index_start, size_t index_end,
|
char *replace_in_str(const char *text, size_t index_start, size_t index_end,
|
||||||
char *replacement)
|
const char *replacement)
|
||||||
{
|
{
|
||||||
char *new;
|
char *new;
|
||||||
size_t len_text;
|
size_t len_text;
|
||||||
|
|
|
||||||
|
|
@ -6,11 +6,11 @@
|
||||||
/* By: jguelen <jguelen@student.42.fr> +#+ +:+ +#+ */
|
/* By: jguelen <jguelen@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/02/25 12:48:39 by jguelen #+# #+# */
|
/* Created: 2025/02/25 12:48:39 by jguelen #+# #+# */
|
||||||
/* Updated: 2025/02/26 13:30:18 by jguelen ### ########.fr */
|
/* Updated: 2025/03/08 14:52:51 by jguelen ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#include "libft.h"
|
#include "libft.h"
|
||||||
|
|
||||||
char *replace_in_str(const char *text, size_t index_start, size_t index_end,
|
char *replace_in_str(const char *text, size_t index_start, size_t index_end,
|
||||||
char *replacement);
|
const char *replacement);
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
/* By: jguelen <marvin@42.fr> +#+ +:+ +#+ */
|
/* By: jguelen <marvin@42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/03/02 13:40:10 by jguelen #+# #+# */
|
/* Created: 2025/03/02 13:40:10 by jguelen #+# #+# */
|
||||||
/* Updated: 2025/03/05 10:58:44 by jguelen ### ########.fr */
|
/* Updated: 2025/03/07 17:25:18 by jguelen ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
|
@ -44,7 +44,7 @@ static char **get_paths_array(t_env *env)
|
||||||
return (path_array);
|
return (path_array);
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,10 @@
|
||||||
/* ::: :::::::: */
|
/* ::: :::::::: */
|
||||||
/* subst.h :+: :+: :+: */
|
/* subst.h :+: :+: :+: */
|
||||||
/* +:+ +:+ +:+ */
|
/* +:+ +:+ +:+ */
|
||||||
/* By: khais <marvin@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/06 17:41:07 by jguelen ### ########.fr */
|
/* Updated: 2025/03/07 17:26:31 by jguelen ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
|
@ -17,11 +17,18 @@
|
||||||
# include "../minishell.h"
|
# include "../minishell.h"
|
||||||
# include <dirent.h>
|
# include <dirent.h>
|
||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
|
# include <errno.h>
|
||||||
|
|
||||||
|
# define PATH_SIZE_INIT 64
|
||||||
|
|
||||||
char *expand_question_mark(t_minishell *app);
|
char *expand_question_mark(t_minishell *app);
|
||||||
t_wordlist *wordlist_var_expansion(t_wordlist *list, t_minishell *app);
|
t_wordlist *wordlist_var_expansion(t_wordlist *list, t_minishell *app);
|
||||||
t_worddesc *word_var_expansion(t_worddesc *word, t_minishell *app);
|
t_worddesc *word_var_expansion(t_worddesc *word, t_minishell *app);
|
||||||
t_wordlist *expand_star(char *file_pattern);
|
|
||||||
|
void build_pattern_checks(char *str, t_worddesc *pattern,
|
||||||
|
char **pattern_check);
|
||||||
|
char fits_pattern(char *str, t_worddesc *pattern);
|
||||||
|
t_wordlist *expand_star(t_worddesc *file_pattern);
|
||||||
char *construct_repeting_char_string(char c, size_t len);
|
char *construct_repeting_char_string(char c, size_t len);
|
||||||
char *ft_get_longest_identifier(char *str);
|
char *ft_get_longest_identifier(char *str);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
|
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/03/06 12:48/00 by khais #+# #+# */
|
/* Created: 2025/03/06 12:48/00 by khais #+# #+# */
|
||||||
/* Updated: 2025/03/06 12:48:00 by khais ### ########.fr */
|
/* Updated: 2025/03/08 14:01:30 by jguelen ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
|
@ -15,7 +15,41 @@
|
||||||
#include "replace_substr.h"
|
#include "replace_substr.h"
|
||||||
#include "../env/env_manip.h"
|
#include "../env/env_manip.h"
|
||||||
|
|
||||||
static char *word_update(t_worddesc *word, size_t i, size_t id_len, char *rep)
|
/*
|
||||||
|
** @Param
|
||||||
|
** word: the worddesc to be modified
|
||||||
|
** i: the index at which the $ marking the start of expansion is located
|
||||||
|
** id_len: the length of the string that constitutes a valid bash
|
||||||
|
** identifier (it is to be noted that it can be zero and yet still
|
||||||
|
** conduct to a replacement of more that just $ if $ is immediately
|
||||||
|
** followed by a digit -- this cans be modified as it is not strictly
|
||||||
|
** required to consider positionnal arguments at all or indeed treat
|
||||||
|
** them as holding no value)
|
||||||
|
** rep: a malloc-allocated string previously calculated to correspond to
|
||||||
|
** the actual value to set as the expansion
|
||||||
|
** This function exists to actually modify the worddesc word by modifying the
|
||||||
|
** word proper inside but also keep the marker string coherent with these
|
||||||
|
** modifications so that further steps can act properly with the type of
|
||||||
|
** expansion and properly field split (word split in the manual) the result or
|
||||||
|
** not. To this end if an expansion occurs outside quotes every character
|
||||||
|
** resulting from it is marked simply with a '$' character and is subject to
|
||||||
|
** future field splitting. If however, the expansion occurs within double quotes
|
||||||
|
** it is not to be subjected to field splitting in the future and every
|
||||||
|
** character resulting from such an expansion is marked with a '&'.
|
||||||
|
**
|
||||||
|
** cf. https://www.gnu.org/software/bash/manual/bash.html#Quoting
|
||||||
|
** section 3.5.7
|
||||||
|
** The shell scans the results of parameter expansion, command substitution, and
|
||||||
|
** arithmetic expansion that did not occur within double quotes for word
|
||||||
|
** splitting.
|
||||||
|
**
|
||||||
|
** NOTE: It frees the malloc-allocated string rep.
|
||||||
|
**
|
||||||
|
** @RETURN In case of allocation error returns NULL, oterwise returns word
|
||||||
|
** itself.
|
||||||
|
*/
|
||||||
|
static t_worddesc *word_update(t_worddesc *word, size_t i, size_t id_len,
|
||||||
|
char *rep)
|
||||||
{
|
{
|
||||||
char *new_word;
|
char *new_word;
|
||||||
size_t rep_len;
|
size_t rep_len;
|
||||||
|
|
@ -27,18 +61,25 @@ static char *word_update(t_worddesc *word, size_t i, size_t id_len, char *rep)
|
||||||
free(rep);
|
free(rep);
|
||||||
free(word->word);
|
free(word->word);
|
||||||
word->word = new_word;
|
word->word = new_word;
|
||||||
rep = construct_repeting_char_string('$', rep_len);
|
if (word->marker[i] == '"')
|
||||||
|
rep = construct_repeting_char_string('&', rep_len);
|
||||||
|
else
|
||||||
|
rep = construct_repeting_char_string('$', rep_len);
|
||||||
if (!rep)
|
if (!rep)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
new_word = replace_in_str(word->mark_string, i, i + id_len + digit, rep);
|
new_word = replace_in_str(word->marker, i, i + id_len + digit, rep);
|
||||||
free(rep);
|
free(rep);
|
||||||
if (!new_word)
|
if (!new_word)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
free(word->mark_string);
|
free(word->marker);
|
||||||
word->mark_string = new_word;
|
word->marker = new_word;
|
||||||
return (new_word);
|
return (word);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Calculates the string corresponding to the value of the variable to be
|
||||||
|
** expanded in the word proper and returns it.
|
||||||
|
*/
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
|
@ -110,9 +151,9 @@ t_worddesc *word_var_expansion(t_worddesc *word, t_minishell *app)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Returns the t_wordlist passed as a parameter where the words have been
|
** Returns the t_wordlist passed as a parameter where the words have been
|
||||||
** modified to contain string that represent the result of parameter expansion
|
** modified to contain strings that represent the result of parameter expansion
|
||||||
** where the introductory '$' character was not single quoted.
|
** where the introductory '$' character was not single quoted.
|
||||||
** We do NOT take the '\' character into account as an escape character here
|
** We DO NOT take the '\' character into account as an escape character here
|
||||||
** under any circumstance per subject requirement.
|
** under any circumstance per subject requirement.
|
||||||
*/
|
*/
|
||||||
t_wordlist *wordlist_var_expansion(t_wordlist *list, t_minishell *app)
|
t_wordlist *wordlist_var_expansion(t_wordlist *list, t_minishell *app)
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
|
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/03/06 13:03/41 by khais #+# #+# */
|
/* Created: 2025/03/06 13:03/41 by khais #+# #+# */
|
||||||
/* Updated: 2025/03/06 13:03:41 by khais ### ########.fr */
|
/* Updated: 2025/03/08 14:06:20 by jguelen ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
|
@ -16,8 +16,8 @@
|
||||||
#include "../env/env.h"
|
#include "../env/env.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Returns a C-compliant malloc-allocated string of length len and complosed
|
** Returns a C-compliant malloc-allocated string of length len and composed
|
||||||
** only of the character c except for the teerminating NULL-byte or NULL in
|
** only of the character c except for the terminating NULL-byte or NULL in
|
||||||
** case of an allocation error.
|
** case of an allocation error.
|
||||||
*/
|
*/
|
||||||
char *construct_repeting_char_string(char c, size_t len)
|
char *construct_repeting_char_string(char c, size_t len)
|
||||||
|
|
|
||||||
|
|
@ -3,20 +3,22 @@
|
||||||
/* ::: :::::::: */
|
/* ::: :::::::: */
|
||||||
/* wildcard_exp.c :+: :+: :+: */
|
/* wildcard_exp.c :+: :+: :+: */
|
||||||
/* +:+ +:+ +:+ */
|
/* +:+ +:+ +:+ */
|
||||||
/* By: khais <marvin@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/06 17:40:42 by jguelen ### ########.fr */
|
/* Updated: 2025/03/08 17:25:03 by jguelen ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#include "ft_printf.h"
|
#include "ft_printf.h"
|
||||||
#include "subst.h"
|
#include "subst.h"
|
||||||
#include "unistd.h"
|
|
||||||
#include "minishell.h"
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** TODO Pre-process file_pattern worddesc for a congruent marker string
|
||||||
|
** TODO Post-process to sort the resulting list regarding ascii order
|
||||||
|
*/
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/* NOTE: Use of errno and the setting of it was OKed by Alexandru in this */
|
/* NOTE: The use of errno and the setting of it was OKed by Alexandru in this */
|
||||||
/* context. */
|
/* context. */
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/*
|
/*
|
||||||
|
|
@ -60,7 +62,7 @@ static t_wordlist *add_file_to_list(t_wordlist **list, char *filename)
|
||||||
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');
|
file_desc = worddesc_create(copy, '\0', NULL); ///////////CHECK IF CONFLICT
|
||||||
if (!file_desc)
|
if (!file_desc)
|
||||||
{
|
{
|
||||||
wordlist_destroy(*list);
|
wordlist_destroy(*list);
|
||||||
|
|
@ -71,20 +73,7 @@ static t_wordlist *add_file_to_list(t_wordlist **list, char *filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Returns true if and only if filename is recognized by pattern, false
|
** TODO Check if return value correct regarding the manual specifically the
|
||||||
** otherwise.
|
|
||||||
** Takes only into account the * wildcard or ?, those characters
|
|
||||||
** NOTE: for a pattern to accept '.' as the first character of a filename
|
|
||||||
** it must be explicitly matched (only for the first character though).
|
|
||||||
** Similarly, '/' is never to be matched except if given explicitly.
|
|
||||||
*/
|
|
||||||
bool fits_pattern(char *string, char *pattern)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** TODO Check if return value correct regarding the manual specifacally the
|
|
||||||
** following:
|
** following:
|
||||||
** cf Bash scans each word for the character '*'.
|
** cf Bash scans each word for the character '*'.
|
||||||
**
|
**
|
||||||
|
|
@ -92,6 +81,10 @@ bool fits_pattern(char *string, char *pattern)
|
||||||
** regarded as a PATTERN, and replaced with an alphabetically sorted list
|
** regarded as a PATTERN, and replaced with an alphabetically sorted list
|
||||||
** of filenames matching the pattern (see: Pattern Matching). If no matching
|
** of filenames matching the pattern (see: Pattern Matching). If no matching
|
||||||
** filenames are found, the word is left unchanged.
|
** filenames are found, the word is left unchanged.
|
||||||
|
** --> TODO this function should be provided with a properly pre-processed
|
||||||
|
** file_pattern where file_pattern->matcher denotes the quoted wildcards
|
||||||
|
** but the quotes themselves unquoted have been removed from word in a manner
|
||||||
|
** keeping the relationship between word and marker coherent.
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
** A function designed to present all possible * or ? filename expansions
|
** A function designed to present all possible * or ? filename expansions
|
||||||
|
|
@ -99,9 +92,13 @@ bool fits_pattern(char *string, char *pattern)
|
||||||
** Does not take into account any other wildcard and does only search the
|
** Does not take into account any other wildcard and does only search the
|
||||||
** current working directory.
|
** current working directory.
|
||||||
** @PARAM A C compliant character string representing a pattern for a filename.
|
** @PARAM A C compliant character string representing a pattern for a filename.
|
||||||
** @RETURN
|
** @RETURN Returns a wordlist for which each entry corresponds to a filename
|
||||||
|
** that matches pattern->word if any file matches in the current directory.
|
||||||
|
** Otherwise return file_pattern itself if nothing matches the perceived
|
||||||
|
** pattern. This list should be alphabetically sorted.
|
||||||
|
** TODO sort the list in growing ascii order. (use of strcmp probable)
|
||||||
*/
|
*/
|
||||||
t_wordlist *expand_star(char *file_pattern)
|
t_wordlist *expand_star(t_worddesc *file_pattern)
|
||||||
{
|
{
|
||||||
struct dirent *new;
|
struct dirent *new;
|
||||||
DIR *current_dir;
|
DIR *current_dir;
|
||||||
|
|
@ -110,8 +107,8 @@ t_wordlist *expand_star(char *file_pattern)
|
||||||
current_dir = open_current_dir();
|
current_dir = open_current_dir();
|
||||||
if (current_dir == NULL)
|
if (current_dir == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
errno = 0;
|
|
||||||
file_wordlist = NULL;
|
file_wordlist = NULL;
|
||||||
|
errno = 0;
|
||||||
new = readdir(current_dir);
|
new = readdir(current_dir);
|
||||||
while (new)
|
while (new)
|
||||||
{
|
{
|
||||||
|
|
@ -126,6 +123,6 @@ t_wordlist *expand_star(char *file_pattern)
|
||||||
if (errno)
|
if (errno)
|
||||||
return (wordlist_destroy(file_wordlist), NULL);
|
return (wordlist_destroy(file_wordlist), NULL);
|
||||||
if (!file_wordlist)
|
if (!file_wordlist)
|
||||||
add_file_to list(&file_wordlist, file_pattern);
|
wordlist_push(file_wordlist, file_pattern);
|
||||||
return (file_wordlist);
|
return (wordlist_quicksort(file_wordlist));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
124
src/subst/wildcard_exp_utils.c
Normal file
124
src/subst/wildcard_exp_utils.c
Normal file
|
|
@ -0,0 +1,124 @@
|
||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* wildcard_exp_utils.c :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: jguelen <jguelen@student.42.fr> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2025/03/07 17:10:01 by jguelen #+# #+# */
|
||||||
|
/* Updated: 2025/03/08 17:21:48 by jguelen ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#include "subst.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Cleanly disposes of a pattern checker two dimensionnal array.
|
||||||
|
*/
|
||||||
|
static void destroy_pattern_check(char **pattern_check, size_t len)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
while (i < len)
|
||||||
|
{
|
||||||
|
free(pattern_check[i]);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
free(pattern_check);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Returns 1 if the currently examined characters in str and pattern can match
|
||||||
|
** allowing to preserve the validity of previous matches one "character" behind
|
||||||
|
** in both strings.
|
||||||
|
** i.e. serves to detect when the currently examined character of str in index i
|
||||||
|
** and the current character of pattern match exactly or the character in
|
||||||
|
** pattern under scrutiny is an unquoted '?'. There is one exception to wit
|
||||||
|
** the character '.' can only be matched exactly if it is the first character of
|
||||||
|
** both str and pattern and explicitly given. That is in this case ? cannot
|
||||||
|
** match it even if it can under all other circumstance.
|
||||||
|
*/
|
||||||
|
static int same_character_or_one_char_wild(char *str, t_worddesc *pattern,
|
||||||
|
size_t i, size_t j)
|
||||||
|
{
|
||||||
|
return (str[i] == pattern->word[j]
|
||||||
|
|| (pattern->word[j] == '?'
|
||||||
|
&& pattern->marker[j] != '\''
|
||||||
|
&& pattern->marker != '"'
|
||||||
|
&& !(i == 1 && pattern->word[i] == '.')));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Fills the table which contains in its most low and right cell 0 if
|
||||||
|
** str does not match the pattern and 1 otherwise.
|
||||||
|
** This construction is only done for the current diectory so no special
|
||||||
|
** treatment is to be considered for '/' characters which otherwise have
|
||||||
|
** to be matched explicitely. We do however consider the case where the '.'
|
||||||
|
** character cannot be matched unless explicitely when in first position
|
||||||
|
** in str.
|
||||||
|
*/
|
||||||
|
void build_pattern_checks(char *str, t_worddesc *pattern,
|
||||||
|
char **pattern_check)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
size_t j;
|
||||||
|
size_t str_len;
|
||||||
|
size_t pattern_len;
|
||||||
|
|
||||||
|
i = 1;
|
||||||
|
str_len = ft_strlen(str);
|
||||||
|
pattern_len = ft_strlen(pattern->word);
|
||||||
|
pattern_check[0][0] = 1;
|
||||||
|
while (i <= str_len)
|
||||||
|
{
|
||||||
|
j = 1;
|
||||||
|
while (j <= pattern_len)
|
||||||
|
{
|
||||||
|
if (same_character_or_one_char_wild(str, pattern->word, i, j))
|
||||||
|
pattern_check[i][j] = pattern_check[i - 1][j - 1];
|
||||||
|
else if (pattern->word[j] == '*' && pattern->marker[j] != '\''
|
||||||
|
&& pattern->marker[j] != '"' && !(i == 1
|
||||||
|
&& pattern->word[i] == '.'))
|
||||||
|
pattern_check[i][j] = !!(pattern_check[i - 1][j]
|
||||||
|
+ pattern_check[i][j - 1]);
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Returns 1 if and only if filename is recognized by pattern, 0
|
||||||
|
** otherwise or -1 in case of error.
|
||||||
|
** Takes only into account the * wildcard or ?, those characters
|
||||||
|
** NOTE: for a pattern to accept '.' as the first character of a filename
|
||||||
|
** it must be explicitly matched (only for the first character though).
|
||||||
|
** Similarly, '/' is never to be matched except if given explicitly.
|
||||||
|
*/
|
||||||
|
char fits_pattern(char *str, t_worddesc *pattern)
|
||||||
|
{
|
||||||
|
char **pattern_check;
|
||||||
|
size_t str_len;
|
||||||
|
size_t pattern_len;
|
||||||
|
size_t i;
|
||||||
|
char ret;
|
||||||
|
|
||||||
|
pattern_len = ft_strlen(pattern->word);
|
||||||
|
str_len = ft_strlen(str);
|
||||||
|
pattern_check = ft_calloc(str_len + 1, sizeof(char *));
|
||||||
|
if (!pattern_check)
|
||||||
|
return (-1);
|
||||||
|
i = 0;
|
||||||
|
while (i <= str_len)
|
||||||
|
{
|
||||||
|
pattern_check[i] = ft_calloc(pattern_len + 1, sizeof(char));
|
||||||
|
if (!pattern_check[i])
|
||||||
|
return (destroy_pattern_check(pattern_check, str_len + 1), NULL);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
build_pattern_checks(str, pattern, pattern_check);
|
||||||
|
ret = pattern_check[str_len][pattern_len];
|
||||||
|
destroy_pattern_check(pattern_check, str_len + 1);
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
|
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/03/06 13:01/15 by khais #+# #+# */
|
/* Created: 2025/03/06 13:01/15 by khais #+# #+# */
|
||||||
/* Updated: 2025/03/06 13:01:15 by khais ### ########.fr */
|
/* Updated: 2025/03/06 18:07:20 by jguelen ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
|
@ -18,6 +18,16 @@
|
||||||
#include "../src/env/env.h"
|
#include "../src/env/env.h"
|
||||||
#include "../src/env/env_manip.h"
|
#include "../src/env/env_manip.h"
|
||||||
|
|
||||||
|
|
||||||
|
static t_worddesc *create_single_word(char *str)
|
||||||
|
{
|
||||||
|
t_wordlist *words = minishell_wordsplit(str);
|
||||||
|
assert(wordlist_get(words, 0) != NULL);
|
||||||
|
assert(wordlist_get(words, 1) == NULL);
|
||||||
|
t_worddesc *word = wordlist_pop(&words);
|
||||||
|
return (word);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Test file for the different expansion/substitution types of minishell.
|
** Test file for the different expansion/substitution types of minishell.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue