Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
# By: ttsubo <ttsubo@student.42.fr> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2025/04/03 12:55:20 by ttsubo #+# #+# #
# Updated: 2025/05/05 18:42:27 by ttsubo ### ########.fr #
# Updated: 2025/05/06 13:15:51 by ttsubo ### ########.fr #
# #
# **************************************************************************** #

Expand Down Expand Up @@ -68,7 +68,8 @@ TOKENIZER_SRC = tokenizer.c tokenizer_error.c read_token.c \
is_quote_closed.c get_token_capa.c is_redirect_validate.c
PARSER_SRC = allocate_cmds.c parser.c parser_utils.c setup_cmds.c \
allocate_cmds_utils.c allocate_cmds_utils_2.c \
expand_env.c expand_tokens.c trim_quote_tokens.c
expand_env.c expand_tokens.c trim_quote_tokens.c \
split_by_quote.c join_expanded_parts.c
BUILTIN_SRC = cd.c exit.c pwd.c echo.c env.c unset.c export.c \
env_utils.c env_utils_2.c env_utils_3.c builtin_utils.c \
export_exec.c export_print_sorted_env.c export_error.c split_key_value.c
Expand Down
11 changes: 5 additions & 6 deletions inc/builtin/expand_env.h → inc/parser/expand_vars.h
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* expand_env.h :+: :+: :+: */
/* expand_vars.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: ttsubo <ttsubo@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/04/26 11:24:25 by ttsubo #+# #+# */
/* Updated: 2025/05/04 12:15:01 by ttsubo ### ########.fr */
/* Updated: 2025/05/06 14:44:25 by ttsubo ### ########.fr */
/* */
/* ************************************************************************** */

#ifndef EXPAND_ENV_H
# define EXPAND_ENV_H
#ifndef EXPAND_VARS_H
# define EXPAND_VARS_H

# include "common.h"
# include "env_utils.h"
# include "struct.h"
# include <stdbool.h>

Expand All @@ -34,6 +33,6 @@ typedef struct s_expand_temp
char *result;
} t_expand_temp;

char *expand_env(char *token, t_minish *minish);
char *expand_vars(const char *token, t_minish *minish);

#endif
21 changes: 19 additions & 2 deletions inc/parser/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,31 @@
/* By: ttsubo <ttsubo@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/04/21 14:14:59 by ttsubo #+# #+# */
/* Updated: 2025/05/05 18:38:15 by ttsubo ### ########.fr */
/* Updated: 2025/05/06 14:26:28 by ttsubo ### ########.fr */
/* */
/* ************************************************************************** */

#ifndef PARSER_H
# define PARSER_H

# include "common.h"
# include "expand_env.h"
# include "env_utils.h"
# include "expand_vars.h"
# include "libft.h"

typedef enum e_quote
{
QUOTE_NONE,
QUOTE_SINGLE,
QUOTE_DOUBLE
} t_quote;

typedef struct s_part
{
char *text;
t_quote quote;
} t_part;

size_t count_cmds(char **tokens);
char **next_cmd_start(char **token_ptr);
t_cmd **calloc_cmds(char **tokens);
Expand All @@ -33,5 +47,8 @@ size_t count_args_until_separator(char **tokens);
int is_separator(char *token);
t_cmd **allocate_cmds(char **tokens);
t_cmd **setup_cmds(t_cmd **cmds, char **tokens);
t_list *split_by_quote(char *token);
char *join_expanded_parts(t_list *parts, t_minish *minish);
char *strjoin_and_free(char *s1, char *s2);

#endif
149 changes: 71 additions & 78 deletions src/parser/expand_env.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,103 +6,96 @@
/* By: ttsubo <ttsubo@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/04/26 09:15:09 by ttsubo #+# #+# */
/* Updated: 2025/04/26 20:56:43 by ttsubo ### ########.fr */
/* Updated: 2025/05/06 15:10:47 by ttsubo ### ########.fr */
/* */
/* ************************************************************************** */

#include "expand_vars.h"
#include "parser.h"

static char *_ft_strndup(const char *s1, size_t n)
static char *_expand_sts(int last_status, size_t *i)
{
char *d;

if (!s1)
return (NULL);
d = malloc(n + 1);
if (!d)
return (NULL);
ft_strlcpy(d, s1, n + 1);
return (d);
*i = *i + 1;
return (ft_itoa(last_status));
}

static char *_join_str(t_expand_temp tmp)
static char *_expand_var(const char *token, size_t *i, t_minish *minish)
{
size_t pre_len;
size_t val_len;
size_t suff_len;
size_t total_len;
char *result;
size_t len;
char *key;
char *value;

pre_len = ft_strlen(tmp.prefix);
val_len = ft_strlen(tmp.value);
suff_len = ft_strlen(tmp.suffix);
total_len = pre_len + val_len + suff_len + 1;
result = malloc(total_len);
if (!result)
return (NULL);
ft_strlcpy(result, tmp.prefix, total_len);
ft_strlcat(result, tmp.value, total_len);
ft_strlcat(result, tmp.suffix, total_len);
return (result);
len = 0;
while (is_key_char(token[*i + len]))
len++;
key = ft_substr(token, *i, len);
value = ft_strdup(get_env_value(minish->env, key));
free_str(&key);
*i += len;
if (!value)
return (ft_strdup(""));
else
return (value);
}

/**
* @brief expand_temp is used to release memory allocations.
*
* @param tmp
* @note tmp->suffix is part of tkn->input, so free() is not executed.
* @note tmp->result is assigned to tkn->input, so free() is not executed.
*/
static void _free_tmp(t_expand_temp *tmp)
static char *_expand_dollar(const char *token, size_t *i, t_minish *minish,
bool *has_expandable)
{
free(tmp->key);
free(tmp->value);
free(tmp->result);
free(tmp->prefix);
free(tmp->suffix);
char *tmp;

*has_expandable = true;
if (token[*i] == '?')
tmp = _expand_sts(minish->last_status, i);
else if (is_key_start(token[*i]))
tmp = _expand_var(token, i, minish);
else
tmp = ft_strdup("$");
return (tmp);
}

static void _set_tmpstr(t_minish *minish, char *token,
t_expand_env *ex_env, t_expand_temp *tmp)
static char *_expand_one(const char *token, t_minish *minish,
bool *has_expandable)
{
tmp->key = _ft_strndup(token + ex_env->key_st, ex_env->key_len);
tmp->value = ft_strdup(get_env_value(minish->env, tmp->key));
if (!tmp->value)
tmp->value = ft_strdup("");
tmp->prefix = _ft_strndup(token, ex_env->pre_len);
tmp->suffix = ft_strdup(token + ex_env->key_st + ex_env->key_len);
tmp->result = _join_str(*tmp);
char *result;
char *tmp;
size_t i;

result = ft_strdup("");
if (!result)
return (NULL);
i = 0;
*has_expandable = false;
while (token[i])
{
if (token[i] == '$')
{
i++;
tmp = _expand_dollar(token, &i, minish, has_expandable);
}
else
tmp = ft_substr(token, i++, 1);
if (!tmp)
return (free_str(&result), NULL);
result = strjoin_and_free(result, tmp);
}
return (result);
}

/**
* @brief Expand env vars beginning with $ in the tkn->input str.
*
* @param tkn
* @param minish
* @return t_tokenizer*
*/
char *expand_env(char *token, t_minish *minish)
char *expand_vars(const char *token, t_minish *minish)
{
const char *env_ptr;
t_expand_env ex_env;
t_expand_temp tmp;
char *result;
bool has_expandable;
char *result;
char *next;

env_ptr = ft_strchr(token, '$');
if (!env_ptr)
return (ft_strdup(token));
ft_bzero(&tmp, sizeof(tmp));
ex_env.key_len = 0;
ex_env.pre_len = env_ptr - token;
ex_env.key_st = ex_env.pre_len + 1;
if (!is_key_start(token[ex_env.key_st]))
return (ft_strdup(token));
while (is_key_char(token[ex_env.key_st + ex_env.key_len]))
ex_env.key_len++;
_set_tmpstr(minish, token, &ex_env, &tmp);
if (!tmp.result)
return (_free_tmp(&tmp), ft_strdup(token));
result = ft_strdup(tmp.result);
_free_tmp(&tmp);
result = ft_strdup(token);
if (!result)
return (NULL);
has_expandable = true;
while (has_expandable)
{
next = _expand_one(result, minish, &has_expandable);
free(result);
result = next;
}
return (result);
}
86 changes: 31 additions & 55 deletions src/parser/expand_tokens.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,23 @@
/* By: ttsubo <ttsubo@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/05/02 17:08:42 by ttsubo #+# #+# */
/* Updated: 2025/05/02 17:52:43 by ttsubo ### ########.fr */
/* Updated: 2025/05/06 15:12:41 by ttsubo ### ########.fr */
/* */
/* ************************************************************************** */

#include "parser.h"

static void _free_part(void *ptr)
{
t_part *part;

part = ptr;
if (!part)
return ;
free(part->text);
free(part);
}

static size_t _tokens_len(char **tokens)
{
size_t i;
Expand All @@ -22,71 +33,36 @@ static size_t _tokens_len(char **tokens)
return (i);
}

/**
* @note pre: $? in str
*/
static char *_expand_dollar(char *str, t_minish *minish)
{
char *pre;
char *suf;
char *sts_str;
char *joined;
char *final;

pre = ft_substr(str, 0, ft_strlen_until(str, '$'));
sts_str = ft_itoa(minish->last_status);
suf = ft_strdup(str + ft_strlen_until(str, '$') + 2);
if (!pre || !sts_str || !suf)
return (free(pre), free(sts_str), free(suf), NULL);
joined = ft_strjoin(pre, sts_str);
final = ft_strjoin(joined, suf);
return (free(pre), free(sts_str), free(suf), free(joined), final);
}

static char *_expand(char *token, t_minish *minish)
char *expand_token(char *token, t_minish *minish)
{
t_list *parts;
char *result;
char *tmp;

result = ft_strdup(token);
if (!result)
parts = split_by_quote(token);
if (!parts)
return (NULL);
while (ft_strchr(result, '$'))
{
tmp = result;
if (ft_strnstr(result, "$?", ft_strlen(result)))
result = _expand_dollar(tmp, minish);
else
result = expand_env(tmp, minish);
free(tmp);
if (!result)
return (NULL);
}
result = join_expanded_parts(parts, minish);
ft_lstclear(&parts, _free_part);
return (result);
}

char **expand_tokens(char **tokens, t_minish *minish)
{
size_t token_i;
size_t len;
char **expanded;
size_t i;
size_t count;
char **result;

len = _tokens_len(tokens);
expanded = ft_calloc(sizeof(char *), len + 1);
if (!expanded)
count = _tokens_len(tokens);
result = ft_calloc(sizeof(char *), count + 1);
if (!result)
return (NULL);
token_i = 0;
while (token_i < len)
i = 0;
while (i < count)
{
expanded[token_i] = _expand(tokens[token_i], minish);
if (!expanded[token_i])
{
while (0 < token_i)
free(expanded[--token_i]);
free(expanded);
return (NULL);
}
token_i++;
result[i] = expand_token(tokens[i], minish);
if (!result[i])
return (free_strs(&result), NULL);
i++;
}
return (expanded);
return (result);
}
Loading