mirror of
https://codeberg.org/la-chouette/minishell.git
synced 2025-12-06 07:28:09 +01:00
Expansion: variable substitution V1 attempt
Norm has been checked, test are not up to date. Wildcard management and filename expansions still to be done.
This commit is contained in:
parent
e348040ea4
commit
fa383c4f17
7 changed files with 152 additions and 82 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -31,3 +31,4 @@ mallocfail_hashes
|
|||
bash.txt
|
||||
.cache/
|
||||
compile_commands.json
|
||||
.vscode
|
||||
|
|
|
|||
|
|
@ -3,18 +3,19 @@
|
|||
/* ::: :::::::: */
|
||||
/* minishell.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: jguelen <marvin@42.fr> +#+ +:+ +#+ */
|
||||
/* By: jguelen <jguelen@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2025/02/24 12:51:21 by jguelen #+# #+# */
|
||||
/* Updated: 2025/02/24 13:04:32 by jguelen ### ########.fr */
|
||||
/* Updated: 2025/03/01 16:59:30 by jguelen ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef MINISHELL_H
|
||||
# define MINISHELL_H
|
||||
|
||||
typedef struct s_minishell
|
||||
typedef struct s_minishell
|
||||
{
|
||||
t_env *env;
|
||||
int last_return_value;
|
||||
} t_minishell;
|
||||
|
||||
|
|
|
|||
|
|
@ -3,10 +3,10 @@
|
|||
/* ::: :::::::: */
|
||||
/* worddesc.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
|
||||
/* By: jguelen <jguelen@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2025/03/11 11:13/50 by khais #+# #+# */
|
||||
/* Updated: 2025/03/11 11:13:50 by khais ### ########.fr */
|
||||
/* Created: 2025/02/13 15:47:58 by khais #+# #+# */
|
||||
/* Updated: 2025/03/21 10:09:06 by jguelen ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
/* By: jguelen <jguelen@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2025/02/23 15:01:40 by jguelen #+# #+# */
|
||||
/* Updated: 2025/02/28 13:43:23 by jguelen ### ########.fr */
|
||||
/* Updated: 2025/03/01 17:00:52 by jguelen ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
# include "../parser/wordlist/wordlist.h"
|
||||
# include "../minishell.h"
|
||||
|
||||
int expand_question_mark(t_minishell *app);
|
||||
int expand_question_mark(t_minishell *app);
|
||||
t_wordlist *wordlist_var_expansion(t_wordlist *list, t_env *env);
|
||||
t_wordlist *expand_star(char *file_pattern);
|
||||
|
||||
|
|
|
|||
|
|
@ -6,56 +6,72 @@
|
|||
/* By: jguelen <jguelen@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2025/02/23 15:02:37 by jguelen #+# #+# */
|
||||
/* Updated: 2025/02/28 18:48:15 by jguelen ### ########.fr */
|
||||
/* Updated: 2025/03/01 17:01:47 by jguelen ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "subst.h"
|
||||
#include "../minishell.h"
|
||||
#include "replace_substr.h"
|
||||
#include "../env/env.h"
|
||||
#include "../env/env_manip.h"
|
||||
|
||||
/*
|
||||
** @RETURN Returns a malloc-allocated string representing the return value of
|
||||
** the last foreground executed pipeline.
|
||||
*/
|
||||
char *expand_question_mark(t_minishell *app)
|
||||
static char *word_update(t_worddesc *word, size_t i, size_t id_len, char *rep)
|
||||
{
|
||||
return (ft_itoa(app->last_return_value));
|
||||
}
|
||||
char *new_word;
|
||||
size_t rep_len;
|
||||
size_t digit;
|
||||
|
||||
/*
|
||||
** Returns the longest possible substring present in str starting at the
|
||||
** beginning that follows the definition of a valid bash identifier.
|
||||
** NOTE(reminder): a valid bash identifier (name) is a non-empty string
|
||||
** starting with a '_' or an alphabetic character and composed only of '_'s or
|
||||
** alphanumerical characters.
|
||||
** The returned string is malloc-allocated.
|
||||
** In case of an allocation error, NULL is returned.
|
||||
*/
|
||||
char *ft_get_longest_identifier(char *str)
|
||||
{
|
||||
char *key;
|
||||
size_t i;
|
||||
|
||||
if (!str || (*str != '_' && !ft_isalpha(*str)))
|
||||
return (ft_strdup(""));
|
||||
i = 1;
|
||||
while (str[i])
|
||||
{
|
||||
if (!ft_isalpha(str[i]) && !ft_isdigit(str[i]) && str[i] != '_')
|
||||
break ;
|
||||
i++;
|
||||
}
|
||||
key = malloc((i + 1)* sizeof(char));
|
||||
if (!key)
|
||||
digit = ft_isdigit(word->word[i + 1]);
|
||||
rep_len = ft_strlen(rep);
|
||||
new_word = replace_in_str(word->word, i, i + id_len + digit, rep);
|
||||
free(rep);
|
||||
free(word->word);
|
||||
word->word = new_word;
|
||||
rep = construct_repeting_char_string('$', rep_len);
|
||||
if (!rep)
|
||||
return (NULL);
|
||||
ft_memcpy(key, str, i);
|
||||
key[i] = '\0';
|
||||
return (key);
|
||||
new_word = replace_in_str(word->mark_string, i, i + id_len + digit, rep);
|
||||
free(rep);
|
||||
if (!new_word)
|
||||
return (NULL);
|
||||
free(word->mark_string);
|
||||
word->mark_string = new_word;
|
||||
return (new_word);
|
||||
}
|
||||
|
||||
static char *calculate_replacement(t_worddesc *word, t_minishell *app, size_t i,
|
||||
size_t *id_len)
|
||||
{
|
||||
char *rep;
|
||||
char *id;
|
||||
|
||||
id = ft_get_longest_identifier(word->word + i + 1);
|
||||
if (!id)
|
||||
return (NULL);
|
||||
*id_len = ft_strlen(id);
|
||||
if (*id_len == 0 && word->word[i + 1] == '?')
|
||||
{
|
||||
rep = expand_question_mark(app);
|
||||
if (!rep)
|
||||
return (NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
rep = env_get_val(app->env, id);
|
||||
if (!rep)
|
||||
rep = strdup("");
|
||||
else
|
||||
rep = strdup(rep);
|
||||
if (!rep)
|
||||
return (NULL);
|
||||
}
|
||||
free(id);
|
||||
return (rep);
|
||||
}
|
||||
|
||||
/*
|
||||
** @Param word should NOT be NULL.
|
||||
** Replace the word field of the t_worddesc pointer word with a new string
|
||||
** corresponding to the replacement of the '$' followed by a valid bash
|
||||
** identifier with the corresponding value if present in env or nothing if
|
||||
|
|
@ -66,50 +82,31 @@ char *ft_get_longest_identifier(char *str)
|
|||
** Similarly if the character following the '$' is neither '_' or
|
||||
** alphanumerical the dollar is removed except for the appearance of a '\0'
|
||||
** signaling the end of the word.
|
||||
** Returns NULL in case of error.
|
||||
** Returns NULL in case of error, or the worddesc pointer word itself if
|
||||
** everything went normally.
|
||||
*/
|
||||
t_worddesc *word_var_expansion(t_worddesc *word, t_env *env)
|
||||
t_worddesc *word_var_expansion(t_worddesc *word, t_minishell *app)
|
||||
{
|
||||
size_t i;
|
||||
char *id;
|
||||
char *tmp;
|
||||
size_t id_len;
|
||||
size_t rep_len;
|
||||
char *rep;
|
||||
|
||||
i = 0;
|
||||
while (((*word)->word)[i])
|
||||
while (word->word[i] && word->word[i + 1])
|
||||
{
|
||||
if (word->flags[i] != '\'' && word->word[i] == '$')
|
||||
if (word->mark_string[i] != '\'' && word->word[i] == '$')
|
||||
{
|
||||
id = ft_get_longest_identifier((word->word) + i + 1);
|
||||
if (!id)
|
||||
rep = calculate_replacement(word, app, i, &id_len);
|
||||
if (!rep)
|
||||
return (NULL);
|
||||
id_len = ft_strlen(id);
|
||||
if ((id_len == 0 && (word->word[i + 1] == '\0'
|
||||
|| word->word[i + 1] == '"' || word->word[i + 1] == '\''))
|
||||
|| (id_len == 1 && ft_isdigit(*id)))
|
||||
{
|
||||
free(id);
|
||||
if (word->word[i + 1] == '\0')
|
||||
continue ;
|
||||
tmp = replace_in_str(word->word, i, i, NULL);
|
||||
free(word->word);
|
||||
word->word = tmp;
|
||||
/////flags update
|
||||
continue ;
|
||||
}
|
||||
rep = env_get_val(env, id);
|
||||
free(id);
|
||||
tmp = replace_in_str(word->word, i, i + id_len, rep);
|
||||
free(rep);
|
||||
if (!tmp)
|
||||
rep_len = ft_strlen(rep);
|
||||
if (word_update(word, i, id_len, rep) == NULL)
|
||||
return (NULL);
|
||||
free(word->word);
|
||||
word->word = tmp;
|
||||
////flags update
|
||||
}
|
||||
i++;
|
||||
i += rep_len;
|
||||
}
|
||||
return (*word);
|
||||
return (word);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -119,18 +116,15 @@ t_worddesc *word_var_expansion(t_worddesc *word, t_env *env)
|
|||
** We do NOT take the '\' character into account as an escape character here
|
||||
** under any circumstance per subject requirement.
|
||||
*/
|
||||
t_wordlist *wordlist_var_expansion(t_wordlist *list, t_env *env)
|
||||
t_wordlist *wordlist_var_expansion(t_wordlist *list, t_minishell *app)
|
||||
{
|
||||
t_wordlist *tmp_list;
|
||||
char *tmp_word;
|
||||
ssize_t idx_start;
|
||||
char *value;
|
||||
|
||||
tmp_list = list;
|
||||
while (tmp_list)
|
||||
{
|
||||
if ((tmp_list->word->flags & W_HASDOLLAR)
|
||||
&& word_var_expansion(tmp_list->word, env) == NULL)
|
||||
&& word_var_expansion(tmp_list->word, app) == NULL)
|
||||
return (NULL);
|
||||
tmp_list = tmp_list->next;
|
||||
}
|
||||
|
|
|
|||
73
src/subst/variable_subst_utils.c
Normal file
73
src/subst/variable_subst_utils.c
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* variable_subst_utils.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: jguelen <jguelen@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2025/03/01 13:04:27 by jguelen #+# #+# */
|
||||
/* Updated: 2025/03/01 17:02:27 by jguelen ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "subst.h"
|
||||
#include "../minishell.h"
|
||||
#include "replace_substr.h"
|
||||
#include "../env/env.h"
|
||||
#include "../env/env_manip.h"
|
||||
|
||||
/*
|
||||
** Returns a C-compliant malloc-allocated string of length len and complosed
|
||||
** only of the character c except for the teerminating NULL-byte or NULL in
|
||||
** case of an allocation error.
|
||||
*/
|
||||
char *construct_repeting_char_string(char c, size_t len)
|
||||
{
|
||||
char *new;
|
||||
|
||||
new = ft_calloc(len + 1, sizeof(char));
|
||||
if (!new)
|
||||
return (NULL);
|
||||
ft_memset(new, c, len);
|
||||
return (new);
|
||||
}
|
||||
|
||||
/*
|
||||
** @RETURN Returns a malloc-allocated string representing the return value of
|
||||
** the last foreground executed pipeline.
|
||||
*/
|
||||
char *expand_question_mark(t_minishell *app)
|
||||
{
|
||||
return (ft_itoa(app->last_return_value));
|
||||
}
|
||||
|
||||
/*
|
||||
** Returns the longest possible substring present in str starting at the
|
||||
** beginning that follows the definition of a valid bash identifier.
|
||||
** NOTE(reminder): a valid bash identifier (name) is a non-empty string
|
||||
** starting with a '_' or an alphabetic character and composed only of '_'s or
|
||||
** alphanumerical characters.
|
||||
** The returned string is malloc-allocated.
|
||||
** In case of an allocation error, NULL is returned.
|
||||
*/
|
||||
char *ft_get_longest_identifier(char *str)
|
||||
{
|
||||
char *key;
|
||||
size_t i;
|
||||
|
||||
if (!str || (*str != '_' && !ft_isalpha(*str)))
|
||||
return (ft_strdup(""));
|
||||
i = 1;
|
||||
while (str[i])
|
||||
{
|
||||
if (!ft_isalpha(str[i]) && !ft_isdigit(str[i]) && str[i] != '_')
|
||||
break ;
|
||||
i++;
|
||||
}
|
||||
key = malloc((i + 1) * sizeof(char));
|
||||
if (!key)
|
||||
return (NULL);
|
||||
ft_memcpy(key, str, i);
|
||||
key[i] = '\0';
|
||||
return (key);
|
||||
}
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
/* By: jguelen <jguelen@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2025/02/23 15:00:18 by jguelen #+# #+# */
|
||||
/* Updated: 2025/02/28 14:23:30 by jguelen ### ########.fr */
|
||||
/* Updated: 2025/03/01 11:07:17 by jguelen ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
|
|
@ -43,6 +43,7 @@ static void test_insert_instr(void)
|
|||
free(line);
|
||||
}
|
||||
|
||||
//Test to be remade since structures changed in the function calls and returns.
|
||||
static void test_env_variable_expansion(void)
|
||||
{
|
||||
char *token;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue