Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
3 changes: 2 additions & 1 deletion inc/common/common.h
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/29 11:44:19 by ttsubo #+# #+# */
/* Updated: 2025/05/05 18:38:08 by ttsubo ### ########.fr */
/* Updated: 2025/05/06 19:19:56 by ttsubo ### ########.fr */
/* */
/* ************************************************************************** */

Expand All @@ -25,6 +25,7 @@ bool is_key_start(int c);
bool is_key_char(int c);
bool is_valid_key(char *str);
bool is_quote(char c);
bool has_closing_quote(const char *s, char quote, size_t i);
void error_mes(char *name, char *mes);

#endif
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
13 changes: 12 additions & 1 deletion src/common/is_quote.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
/* By: ttsubo <ttsubo@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/05/05 14:07:03 by ttsubo #+# #+# */
/* Updated: 2025/05/05 14:15:15 by ttsubo ### ########.fr */
/* Updated: 2025/05/06 19:20:10 by ttsubo ### ########.fr */
/* */
/* ************************************************************************** */

Expand All @@ -16,3 +16,14 @@ bool is_quote(char c)
{
return (c == '\'' || c == '"');
}

bool has_closing_quote(const char *s, char quote, size_t i)
{
while (s[i])
{
if (s[i] == quote)
return (true);
i++;
}
return (false);
}
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);
}
Loading