[ADD] export builtin (unfinished)
This commit is contained in:
parent
f578b5311b
commit
532b4e959f
12 changed files with 199 additions and 66 deletions
2
Makefile
2
Makefile
|
@ -7,7 +7,7 @@ INCLUDES = include/ libtf/ libft/
|
|||
# .c files in src/ without the extension
|
||||
CODE = main ask_command error path parse_command exec_command builtin builtin2\
|
||||
signals cool_readline variables parse_command_utils \
|
||||
parse_command_read_string parse_command_read_element
|
||||
parse_command_read_string parse_command_read_element variables_utils
|
||||
# directories to 'make'
|
||||
LIBRARIES = libtf libft
|
||||
# .a files to include
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
/* By: jschaft <cecile.schaft@orange.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/04/23 14:15:12 by mcolonna #+# #+# */
|
||||
/* Updated: 2024/06/28 11:52:13 by mcolonna ### ########.fr */
|
||||
/* Updated: 2024/06/28 14:25:50 by mcolonna ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
|
@ -27,4 +27,7 @@ int echo_builtin(const char **argv);
|
|||
// Execute cd builtin
|
||||
int cd_builtin(t_env *env, t_call call);
|
||||
|
||||
// Execute export builtin
|
||||
int export_builtin(t_env *env, t_call call);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
/* By: jschaft <cecile.schaft@orange.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/04/23 14:15:12 by mcolonna #+# #+# */
|
||||
/* Updated: 2024/06/13 16:39:07 by mcolonna ### ########.fr */
|
||||
/* Updated: 2024/06/28 14:01:25 by mcolonna ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
|
@ -21,7 +21,6 @@ typedef struct s_env
|
|||
t_memclass mc_command; // open during the execution of a command
|
||||
int errorstatus; // Error status of the last executed command
|
||||
t_list *variables; // Shell variables
|
||||
char *const *envp; // Environment variables
|
||||
bool exit; // Set to true to exit minishell
|
||||
} t_env;
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
/* By: mcolonna <marvin@42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/06/27 13:43:21 by mcolonna #+# #+# */
|
||||
/* Updated: 2024/06/28 13:10:43 by mcolonna ### ########.fr */
|
||||
/* Updated: 2024/06/28 14:22:50 by mcolonna ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
|
@ -17,6 +17,7 @@ typedef struct s_variable
|
|||
{
|
||||
const char *name;
|
||||
const char *value;
|
||||
bool exported;
|
||||
} t_variable;
|
||||
|
||||
// Set a variable to a new value.
|
||||
|
@ -26,4 +27,13 @@ void variables_set(t_list *variables, const char *name,
|
|||
// Get the value of a variable from its name.
|
||||
const char *variables_get(t_list *variables, const char *name);
|
||||
|
||||
// Set a variable as exported.
|
||||
void variables_export(t_list *variables, const char *name);
|
||||
|
||||
// Unset a variable.
|
||||
void variables_unset(t_list *variables, const char *name);
|
||||
|
||||
// Get a envp of all exported variables.
|
||||
char *const *variables_envp(t_list *variables, t_memclass mc);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
/* By: jschaft <cecile.schaft@orange.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/06/03 12:02:45 by jschaft #+# #+# */
|
||||
/* Updated: 2024/06/28 13:12:49 by mcolonna ### ########.fr */
|
||||
/* Updated: 2024/06/28 14:24:40 by mcolonna ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
|
@ -29,12 +29,12 @@ bool is_builtin(const char *str)
|
|||
return (
|
||||
ft_strncmp(str, "cd", 3) == 0
|
||||
|| ft_strncmp(str, "exit", 5) == 0
|
||||
// || ft_strncmp(str, "export", 7) == 0
|
||||
|| ft_strncmp(str, "export", 7) == 0
|
||||
|| ft_strncmp(str, "env", 4) == 0
|
||||
|| ft_strncmp(str, "pwd", 4) == 0
|
||||
|| ft_strncmp(str, "echo", 5) == 0
|
||||
|| ft_strncmp(str, "unset", 6) == 0
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
// Execute the builtin pwd for the current directory.
|
||||
|
@ -49,16 +49,21 @@ static int pwd_builtin(void)
|
|||
return (0);
|
||||
}
|
||||
|
||||
static int env_builtin(char *const envp[])
|
||||
// TODO check arguments
|
||||
static int env_builtin(t_env *env, t_call call)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
const t_memclass mc = mem_subclass(fatal_error, env->mc_global);
|
||||
char *const *envp = variables_envp(env->variables, mc);
|
||||
|
||||
(void)call;
|
||||
i = 0;
|
||||
while (envp[i] != NULL)
|
||||
{
|
||||
printf("%s\n", envp[i]);
|
||||
i++;
|
||||
}
|
||||
mem_freeall(mc);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -72,8 +77,8 @@ int exec_builtin(t_env *env, t_call call)
|
|||
return (cd_builtin(env, call));
|
||||
if (ft_strncmp(call.program, "exit", 5) == 0)
|
||||
env->exit = true;
|
||||
/* if (ft_strncmp(call.program, "export", 7) == 0)
|
||||
return (export_builtin(call.argv));*/
|
||||
if (ft_strncmp(call.program, "export", 7) == 0)
|
||||
return (export_builtin(env, call));
|
||||
if (ft_strncmp(call.program, "unset", 6) == 0)
|
||||
return (unset_builtin(env, call));
|
||||
if (ft_strncmp(call.program, "pwd", 4) == 0)
|
||||
|
@ -81,6 +86,6 @@ int exec_builtin(t_env *env, t_call call)
|
|||
if (ft_strncmp(call.program, "echo", 5) == 0)
|
||||
return (echo_builtin((const char **)call.argv));
|
||||
if (ft_strncmp(call.program, "env", 4) == 0)
|
||||
return (env_builtin(env->envp));
|
||||
return (env_builtin(env, call));
|
||||
return (1);
|
||||
}
|
||||
|
|
|
@ -6,12 +6,23 @@
|
|||
/* By: jschaft <cecile.schaft@orange.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/06/25 13:28:29 by jschaft #+# #+# */
|
||||
/* Updated: 2024/06/28 12:04:26 by mcolonna ### ########.fr */
|
||||
/* Updated: 2024/06/28 14:26:05 by mcolonna ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "include.h"
|
||||
|
||||
// TODO 'name=value' notation
|
||||
int export_builtin(t_env *env, t_call call)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
while (call.argv[++i])
|
||||
variables_export(env->variables, call.argv[i]);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int echo_builtin(const char **argv)
|
||||
{
|
||||
int i;
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
/* By: jschaft <cecile.schaft@orange.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/04/24 13:48:00 by jschaft #+# #+# */
|
||||
/* Updated: 2024/06/28 12:54:07 by mcolonna ### ########.fr */
|
||||
/* Updated: 2024/06/28 14:04:08 by mcolonna ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
|
@ -86,19 +86,23 @@ static int create_pipes(t_exec_command_global *global, t_command command)
|
|||
static int exec_each_call(t_exec_command_global *global,
|
||||
t_command command, t_env *env)
|
||||
{
|
||||
int i;
|
||||
int r;
|
||||
int inout[2];
|
||||
int i;
|
||||
int r;
|
||||
int inout[2];
|
||||
t_memclass mc;
|
||||
|
||||
i = -1;
|
||||
while (++i < global->nb_calls)
|
||||
{
|
||||
mc = mem_subclass(fatal_error, global->mc);
|
||||
inout[0] = global->pipes[i].pipe[0];
|
||||
inout[1] = global->pipes[i + 1].pipe[1];
|
||||
if (is_builtin(command.calls[i].program))
|
||||
r = exec_builtin(env, command.calls[i]);
|
||||
else
|
||||
r = execute_call(global, command.calls[i], inout, env->envp);
|
||||
r = execute_call(global, command.calls[i], inout,
|
||||
variables_envp(env->variables, mc));
|
||||
mem_freeall(mc);
|
||||
if (r)
|
||||
return (r);
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
/* By: jschaft <cecile.schaft@orange.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/04/23 14:33:45 by mcolonna #+# #+# */
|
||||
/* Updated: 2024/06/28 12:53:23 by mcolonna ### ########.fr */
|
||||
/* Updated: 2024/06/28 14:10:09 by mcolonna ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
|
@ -29,6 +29,7 @@ static t_list variables_from_envp(t_env env, char *const envp[])
|
|||
var = mem_alloc(fatal_error, env.mc_global, sizeof(t_variable));
|
||||
var->name = splitted[0];
|
||||
var->value = splitted[1];
|
||||
var->exported = true;
|
||||
list_add(fatal_error, &r, var);
|
||||
}
|
||||
return (r);
|
||||
|
@ -92,7 +93,6 @@ int main(const int argc, const char *argv[], char *const envp[])
|
|||
set_global_mc(env.mc_global);
|
||||
env.mc_command = NULL;
|
||||
env.errorstatus = 0;
|
||||
env.envp = envp;
|
||||
variables = variables_from_envp(env, envp);
|
||||
env.variables = &variables;
|
||||
start(&env);
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
/* By: mcolonna <marvin@42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/04/24 13:47:40 by mcolonna #+# #+# */
|
||||
/* Updated: 2024/06/28 13:14:15 by mcolonna ### ########.fr */
|
||||
/* Updated: 2024/06/28 14:10:53 by mcolonna ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
|
@ -59,8 +59,8 @@ static bool parse_variable_set_command(
|
|||
streamstr_init(&args->stream, command);
|
||||
skip_blank(&args->stream);
|
||||
name = str_dup(fatal_error, args->mc, "");
|
||||
read_only(args, &var.name, SYMBOL_CHARS);
|
||||
if (str_len(var.name) == 0 || stream_pop(&args->stream) != '=')
|
||||
read_only(args, &name, SYMBOL_CHARS);
|
||||
if (str_len(name) == 0 || stream_pop(&args->stream) != '=')
|
||||
return (false);
|
||||
value = read_string(args, "<>|/");
|
||||
if (args->r.error)
|
||||
|
|
105
src/variables.c
105
src/variables.c
|
@ -6,52 +6,12 @@
|
|||
/* By: mcolonna <marvin@42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/04/24 13:47:40 by mcolonna #+# #+# */
|
||||
/* Updated: 2024/06/28 13:11:41 by mcolonna ### ########.fr */
|
||||
/* Updated: 2024/06/28 14:33:14 by mcolonna ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "include.h"
|
||||
|
||||
static void variables_free(t_list *variables, t_list_element *el)
|
||||
{
|
||||
if (el->previous)
|
||||
el->previous->next = el->next;
|
||||
else
|
||||
variables->first = el->next;
|
||||
if (el->next)
|
||||
el->next->previous = el->previous;
|
||||
else
|
||||
variables->last = el->previous;
|
||||
variables->size--;
|
||||
mem_free(el->value);
|
||||
mem_free(el);
|
||||
}
|
||||
|
||||
// Return a pointer to the variable 'name'.
|
||||
// (An undefined variable is considered of an empty value)
|
||||
static t_variable *variables_find(t_list *variables, const char *name)
|
||||
{
|
||||
t_list_element *el;
|
||||
t_list_element *next;
|
||||
t_variable *r;
|
||||
|
||||
el = variables->first;
|
||||
while (el)
|
||||
{
|
||||
next = el->next;
|
||||
r = (t_variable *)el->value;
|
||||
if (str_eq(r->name, name))
|
||||
return (r);
|
||||
if (str_eq(r->value, ""))
|
||||
variables_free(variables, el);
|
||||
el = next;
|
||||
}
|
||||
r = mem_alloc(fatal_error, variables->mc, sizeof(t_variable));
|
||||
r->name = str_dup(fatal_error, variables->mc, name);
|
||||
r->value = "";
|
||||
list_add(fatal_error, variables, r);
|
||||
return (r);
|
||||
}
|
||||
#include "variables_utils.h"
|
||||
|
||||
void variables_set(t_list *variables, const char *name, const char *value)
|
||||
{
|
||||
|
@ -63,3 +23,64 @@ const char *variables_get(t_list *variables, const char *name)
|
|||
{
|
||||
return (variables_find(variables, name)->value);
|
||||
}
|
||||
|
||||
void variables_export(t_list *variables, const char *name)
|
||||
{
|
||||
variables_find(variables, name)->exported = true;
|
||||
}
|
||||
|
||||
void variables_unset(t_list *variables, const char *name)
|
||||
{
|
||||
t_list_element *el;
|
||||
t_list_element *next;
|
||||
t_variable *r;
|
||||
|
||||
el = variables->first;
|
||||
while (el)
|
||||
{
|
||||
next = el->next;
|
||||
r = (t_variable *)el->value;
|
||||
if (str_eq(r->name, name))
|
||||
{
|
||||
if (el->previous)
|
||||
el->previous->next = el->next;
|
||||
else
|
||||
variables->first = el->next;
|
||||
if (el->next)
|
||||
el->next->previous = el->previous;
|
||||
else
|
||||
variables->last = el->previous;
|
||||
variables->size--;
|
||||
mem_free(el->value);
|
||||
mem_free(el);
|
||||
}
|
||||
el = next;
|
||||
}
|
||||
}
|
||||
|
||||
char *const *variables_envp(t_list *variables, t_memclass mc)
|
||||
{
|
||||
t_list_element *el;
|
||||
const int count = variables_countexported(variables);
|
||||
char **r;
|
||||
int i;
|
||||
char *tmp;
|
||||
|
||||
r = mem_alloc(fatal_error, mc, (count + 1) * sizeof(char *));
|
||||
el = variables->first;
|
||||
i = -1;
|
||||
while (el)
|
||||
{
|
||||
if (((t_variable *)(el->value))->exported)
|
||||
{
|
||||
tmp = str_join(
|
||||
fatal_error, mc, ((t_variable *)(el->value))->name, "=");
|
||||
r[++i] = str_join(
|
||||
fatal_error, mc, tmp, ((t_variable *)(el->value))->value);
|
||||
mem_free(tmp);
|
||||
}
|
||||
el = el->next;
|
||||
}
|
||||
r[++i] = NULL;
|
||||
return (r);
|
||||
}
|
||||
|
|
55
src/variables_utils.c
Normal file
55
src/variables_utils.c
Normal file
|
@ -0,0 +1,55 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* variables_utils.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: mcolonna <marvin@42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/04/24 13:47:40 by mcolonna #+# #+# */
|
||||
/* Updated: 2024/06/28 14:30:52 by mcolonna ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "include.h"
|
||||
#include "variables_utils.h"
|
||||
|
||||
t_variable *variables_find(t_list *variables, const char *name)
|
||||
{
|
||||
t_list_element *el;
|
||||
t_list_element *next;
|
||||
t_variable *r;
|
||||
|
||||
el = variables->first;
|
||||
while (el)
|
||||
{
|
||||
next = el->next;
|
||||
r = (t_variable *)el->value;
|
||||
if (str_eq(r->name, name))
|
||||
return (r);
|
||||
if (str_eq(r->value, "") && !r->exported)
|
||||
variables_unset(variables, r->name);
|
||||
el = next;
|
||||
}
|
||||
r = mem_alloc(fatal_error, variables->mc, sizeof(t_variable));
|
||||
r->name = str_dup(fatal_error, variables->mc, name);
|
||||
r->value = "";
|
||||
r->exported = false;
|
||||
list_add(fatal_error, variables, r);
|
||||
return (r);
|
||||
}
|
||||
|
||||
int variables_countexported(t_list *variables)
|
||||
{
|
||||
int r;
|
||||
t_list_element *el;
|
||||
|
||||
r = 0;
|
||||
el = variables->first;
|
||||
while (el)
|
||||
{
|
||||
if (((t_variable *)(el->value))->exported)
|
||||
r++;
|
||||
el = el->next;
|
||||
}
|
||||
return (r);
|
||||
}
|
25
src/variables_utils.h
Normal file
25
src/variables_utils.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* variables_utils.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: mcolonna <marvin@42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/04/24 13:47:40 by mcolonna #+# #+# */
|
||||
/* Updated: 2024/06/28 14:35:55 by mcolonna ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef VARIABLES_UTILS_H
|
||||
# define VARIABLES_UTILS_H
|
||||
|
||||
# include "include.h"
|
||||
|
||||
// Return a pointer to the variable 'name'.
|
||||
// (An undefined variable is considered of an empty value)
|
||||
t_variable *variables_find(t_list *variables, const char *name);
|
||||
|
||||
// Return the number of exported variables.
|
||||
int variables_countexported(t_list *variables);
|
||||
|
||||
#endif
|
Loading…
Add table
Reference in a new issue