Implement the export function, change tokenization
authorLukas Jiriste <ljiriste@student.42prague.com>
Fri, 23 Aug 2024 16:46:21 +0000 (18:46 +0200)
committerLukas Jiriste <ljiriste@student.42prague.com>
Fri, 23 Aug 2024 16:46:21 +0000 (18:46 +0200)
The tokenization had to be changed because "export te=te" was refused by
the parser. The "te=te" part was tokenized as ASSIGNMENT_WORD which can
only occur before command. So any ASSIGNMENT_WORD after command name is
now recognized as WORD.

Makefile
inc/execution.h
src/builtins/export.c [new file with mode: 0644]
src/execution.c
src/tokenization.c

index f56c1b4795f96ddd87264e24967781cfc5b31839..dc168cddcefc7c2a9aa794e49d59d32c9f814fc8 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -37,6 +37,7 @@ SOURCES :=    main.c                          \
                        builtins/echo.c         \
                        builtins/pwd.c          \
                        builtins/env.c          \
+                       builtins/export.c       \
 
 SOURCES := $(addprefix $(SRCDIR)/, $(SOURCES))
 
index 6fc5f3da1c59c19226afe20b7958e600595d8f67..9e6a39ae8cf6d4ad882b141df06bc244e178b16f 100644 (file)
@@ -6,20 +6,28 @@
 /*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/08/02 17:40:19 by ljiriste          #+#    #+#             */
-/*   Updated: 2024/08/22 13:35:41 by lnikolov         ###   ########.fr       */
+/*   Updated: 2024/08/23 18:01:03 by ljiriste         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 #ifndef EXECUTION_H
 # define EXECUTION_H
 
+#include "minishell.h"
+
 const char     *get_env_var_value(const t_execution_env *env,
                                const char *var_name);
 int                    set_env_var_value(t_execution_env *env, const char *var_name,
                                const char *new_value);
+char           *get_var_name(const char *line);
+ssize_t                get_var_index(const t_vec *vars, const char *var_name);
+const char     *get_var_value(const t_vec *vars, const char *var_name);
+int                    set_var_value(t_vec *vars, const char *name, const char *value);
+
 int            cd(int argc, char **argv, t_execution_env *env);
 int            echo(int argc, char **argv);
 int            pwd(void);
 int            ft_env(int argc, t_execution_env *env);
+int            export(int argc, char **argv, t_execution_env *env);
 
 #endif // EXECUTION_H
diff --git a/src/builtins/export.c b/src/builtins/export.c
new file mode 100644 (file)
index 0000000..de808e2
--- /dev/null
@@ -0,0 +1,75 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   export.c                                           :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2024/08/23 09:40:38 by ljiriste          #+#    #+#             */
+/*   Updated: 2024/08/23 18:06:00 by ljiriste         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "execution.h"
+#include "minishell.h"
+#include <stdlib.h>
+
+static void            unset_single(const char *name, t_execution_env *env)
+{
+       ssize_t index;
+
+       index = get_var_index(&env->vars->other, name);
+       if (index >= 0)
+               ft_vec_erase(&env->vars->other, index, free_str);
+       index = get_var_index(&env->vars->exported, name);
+       if (index >= 0)
+               ft_vec_erase(&env->vars->exported, index, free_str);
+       return ;
+}
+
+static int     export_single(const char *var, t_execution_env *env)
+{
+       char            *name;
+       char            *value;
+       const char      *const_value;
+       int                     res;
+
+       name = get_var_name(var);
+       if (!name || !name[0] || (var[ft_strlen(name)] != '=' && var[ft_strlen(name)] != '\0'))
+       {
+               free(name);
+               return (1);
+       }
+       if (var[ft_strlen(name)] == '=')
+               const_value = var + ft_strlen(name) + 1;
+       else
+       {
+               const_value = get_env_var_value(env, name);
+               if (!const_value)
+                       const_value = "";
+       }
+       value = ft_strdup(const_value);
+       if (!value)
+       {
+               free(name);
+               return (1);
+       }
+       unset_single(name, env);
+       res = set_var_value(&env->vars->exported, name, value);
+       free(name);
+       free(value);
+       return (res);
+}
+
+int    export(__attribute__((unused)) int argc, char **argv, t_execution_env *env)
+{
+       size_t  i;
+
+       i = 1;
+       while (argv[i])
+       {
+               export_single(argv[i], env);
+               ++i;
+       }
+       return (0);
+}
index b8dd62658f26485bdfa1112ba7eeeda9fe5f8ff2..a43309676d1c28e69f474c7ad5775e3ba7d0628a 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: lnikolov <lnikolov@student.42prague.com    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/07/21 08:57:54 by ljiriste          #+#    #+#             */
-/*   Updated: 2024/08/23 16:17:56 by ljiriste         ###   ########.fr       */
+/*   Updated: 2024/08/23 17:48:17 by ljiriste         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -784,6 +784,8 @@ int is_builtin(const char *str)
                return (1);
        if (!ft_strcmp(str, "env"))
                return (1);
+       if (!ft_strcmp(str, "export"))
+               return (1);
        return (0);
 }
 
@@ -807,6 +809,8 @@ int ex_builtin(char **fields, __attribute__((unused)) t_vec *assignments, __attr
                env->ret_val = pwd();
        else if (!ft_strcmp(fields[0], "env"))
                env->ret_val = ft_env(count_fields(fields), env);
+       else if (!ft_strcmp(fields[0], "export"))
+               env->ret_val = export(count_fields(fields), fields, env);
        else
                return (-1);
        return (0);
index 923c8e1693c5636037932351312e195d1cb54e3d..2c3839238cc8a68afd57a598a48cbd3bb9916ad9 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/06/21 16:34:43 by ljiriste          #+#    #+#             */
-/*   Updated: 2024/08/08 10:34:41 by ljiriste         ###   ########.fr       */
+/*   Updated: 2024/08/23 18:43:53 by ljiriste         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -66,7 +66,7 @@ static int    can_expand_operator(t_vec *current_token, char c)
        return (res);
 }
 
-static const char      *g_tokens[] = {
+static const char      *g_tokens[12] = {
        "WORD",
        "ASSIGNMENT_WORD",
        "IO_NUMBER",
@@ -217,6 +217,50 @@ int        finish_token(t_vec *tokens, t_vec *current_token, char next)
        return (ft_vec_init(current_token, sizeof(char)) != success);
 }
 
+int    is_redirection_operator(const t_token *token)
+{
+       return (token->type == g_tokens[LESS]
+                       || token->type == g_tokens[DLESS]
+                       || token->type == g_tokens[GREAT]
+                       || token->type == g_tokens[DGREAT]);
+}
+
+void   filter_assignment_word(t_vec *tokens)
+{
+       size_t                  i;
+       t_token                 *token;
+       const t_token   *prev_token;
+
+       i = 0;
+       while (i < tokens->size)
+       {
+               token = ft_vec_access(tokens, i);
+               if (i == 0)
+               {
+                       ++i;
+                       continue ;
+               }
+               prev_token = ft_vec_caccess(tokens, i - 1);
+               if (prev_token->type == g_tokens[ASSIGNMENT_WORD]
+                               || prev_token->type == g_tokens[AND_IF]
+                               || prev_token->type == g_tokens[OR_IF])
+               {
+                       ++i;
+                       continue ;
+               }
+               if (i == 1 || prev_token->type != g_tokens[WORD])
+               {
+                       ++i;
+                       token->type = (char *)g_tokens[WORD];
+                       continue ;
+               }
+               prev_token = ft_vec_caccess(tokens, i - 2);
+               if (!is_redirection_operator(prev_token))
+                       token->type = (char *)g_tokens[WORD];
+               ++i;
+       }
+}
+
 int    tokenize(char **line, t_vec *tokens)
 {
        t_vec   current_token;
@@ -262,5 +306,6 @@ int tokenize(char **line, t_vec *tokens)
        if (res)
                ft_vec_free(tokens, free_token);
        ft_vec_free(&current_token, NULL);
+       filter_assignment_word(tokens);
        return (res);
 }