merge
This commit is contained in:
commit
01722c4e21
16 changed files with 211 additions and 142 deletions
9
Makefile
9
Makefile
|
@ -7,7 +7,8 @@ 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 export_print_builtin \
|
||||
parse_command_read_string parse_command_read_element variables_utils
|
||||
parse_command_read_string parse_command_read_element variables_utils \
|
||||
export_builtin variables2
|
||||
# directories to 'make'
|
||||
LIBRARIES = libtf libft
|
||||
# .a files to include
|
||||
|
@ -17,7 +18,7 @@ LIBRARIES_LINK =
|
|||
# to use with the flag -l
|
||||
LINK =
|
||||
# flags to add to the compiler
|
||||
MORE_FLAGS += $(addprefix -L,$(LIBRARIES_LINK)) $(addprefix -l,$(LIBRARIES_LINK) $(LINK)) $(addprefix -I,$(INCLUDES))
|
||||
MORE_FLAGSS = $(MORE_FLAGS) $(addprefix -L,$(LIBRARIES_LINK)) $(addprefix -l,$(LIBRARIES_LINK) $(LINK)) $(addprefix -I,$(INCLUDES))
|
||||
##### END OF THE INTERESTING PART #####
|
||||
|
||||
|
||||
|
@ -55,7 +56,7 @@ debug :
|
|||
|
||||
$(NAME) : $(O_FILES) $(LIBRARIES)
|
||||
@echo "\e[30;47;1m $(NAME): linking... \e[0m"
|
||||
$(CC) -lreadline -o $(NAME) $(O_FILES) $(LIBRARIES_FILES) $(MORE_FLAGS)
|
||||
$(CC) -lreadline -o $(NAME) $(O_FILES) $(LIBRARIES_FILES) $(MORE_FLAGSS)
|
||||
@echo "\e[30;47;1m $(NAME): linked! \e[0m"
|
||||
|
||||
$(LIBRARIES) :
|
||||
|
@ -68,6 +69,6 @@ endif
|
|||
@echo "\e[30;47;1m $(NAME): library $@ made! \e[0m"
|
||||
|
||||
%.o : %.c
|
||||
$(CC) -c $< -o $@ $(MORE_FLAGS)
|
||||
$(CC) -c $< -o $@ $(MORE_FLAGSS)
|
||||
|
||||
.PHONY : all debug clean fclean re $(LIBRARIES)
|
||||
|
|
3
dev/nocluster.sh
Executable file
3
dev/nocluster.sh
Executable file
|
@ -0,0 +1,3 @@
|
|||
# call this file with "source dev/nocluster.sh"
|
||||
|
||||
alias makee="make MORE_FLAGS=\"-lreadline\""
|
|
@ -1,2 +1,2 @@
|
|||
#!/bin/bash
|
||||
valgrind --leak-check=full --show-leak-kinds=all --suppressions=dev/supp ./minishell
|
||||
valgrind --track-origins=yes --leak-check=full --show-leak-kinds=all --suppressions=dev/supp ./minishell
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
/* By: jschaft <cecile.schaft@orange.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/04/23 14:15:12 by mcolonna #+# #+# */
|
||||
/* Updated: 2024/07/04 11:48:47 by mcolonna ### ########.fr */
|
||||
/* Updated: 2024/07/04 12:02:43 by mcolonna ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
|
@ -15,25 +15,29 @@
|
|||
|
||||
# include "include.h"
|
||||
|
||||
// for the 'std' parameter in all these functions:
|
||||
// - std[0] is stdin
|
||||
// - std[1] is stdout
|
||||
|
||||
// Check if the command is a builtin.
|
||||
bool is_builtin(const char *str);
|
||||
|
||||
// Execute the builtin command
|
||||
int exec_builtin(t_env *env, t_call call);
|
||||
int exec_builtin(t_env *env, t_call call, int std[2]);
|
||||
|
||||
// Execute echo builtin
|
||||
int echo_builtin(t_env *env, t_call call);
|
||||
int echo_builtin(t_env *env, t_call call, int std[2]);
|
||||
|
||||
// Execute cd builtin
|
||||
int cd_builtin(t_env *env, t_call call);
|
||||
int cd_builtin(t_env *env, t_call call, int std[2]);
|
||||
|
||||
// Execute export builtin with no arguments
|
||||
int export_print_builtin(t_env *env, t_call call);
|
||||
int export_print_builtin(t_env *env, t_call call, int std[2]);
|
||||
|
||||
// Execute export builtin
|
||||
int export_builtin(t_env *env, t_call call);
|
||||
int export_builtin(t_env *env, t_call call, int std[2]);
|
||||
|
||||
// Execute exit builtin
|
||||
int exit_builtin(t_env *env, t_call call);
|
||||
int exit_builtin(t_env *env, t_call call, int std[2]);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
/* By: jschaft <cecile.schaft@orange.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/04/23 14:15:12 by mcolonna #+# #+# */
|
||||
/* Updated: 2024/06/28 14:01:25 by mcolonna ### ########.fr */
|
||||
/* Updated: 2024/07/01 11:12:51 by mcolonna ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
|
@ -17,11 +17,11 @@
|
|||
|
||||
typedef struct s_env
|
||||
{
|
||||
t_memclass mc_global; // open during all the runtime
|
||||
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
|
||||
bool exit; // Set to true to exit minishell
|
||||
t_memclass mc_global;
|
||||
t_memclass mc_command;
|
||||
int errorstatus;
|
||||
t_list *variables;
|
||||
bool exit;
|
||||
} t_env;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
/* By: jschaft <cecile.schaft@orange.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/04/23 14:15:12 by mcolonna #+# #+# */
|
||||
/* Updated: 2024/06/27 13:47:56 by mcolonna ### ########.fr */
|
||||
/* Updated: 2024/07/01 11:16:02 by mcolonna ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
|
@ -18,26 +18,25 @@
|
|||
// Represents a call to a program (the program name and its arguments)
|
||||
typedef struct s_call
|
||||
{
|
||||
const char *program; // path of the program to call.
|
||||
int argc; // number of arguments given
|
||||
char *const *argv; // arguments given (ended by NULL)
|
||||
// (argc and argv must include the program name)
|
||||
const char *program;
|
||||
int argc;
|
||||
char *const *argv;
|
||||
} t_call;
|
||||
|
||||
// Represents a command given by the user.
|
||||
typedef struct s_command
|
||||
{
|
||||
int error; // 0 if parse_command() succeded, error status if not
|
||||
bool empty; // true if there isn't anything to do
|
||||
const t_call *calls; // all calls to programs (ended by .program == NULL)
|
||||
int input_fd; // fd to use with '<' redirection (0 by default)
|
||||
int output_fd; // fd to use with '>' redirection (1 by default)
|
||||
int error;
|
||||
bool empty;
|
||||
const t_call *calls;
|
||||
int input_fd;
|
||||
int output_fd;
|
||||
} t_command;
|
||||
|
||||
// An element of a list of pipes
|
||||
typedef struct s_pipes
|
||||
{
|
||||
int pipe[2]; // Simple pipe, we write on pipe[1] and we read on pipe[0]
|
||||
int pipe[2];
|
||||
} t_pipes;
|
||||
|
||||
// Return the t_command representing the command given by the user.
|
||||
|
|
|
@ -6,13 +6,16 @@
|
|||
/* By: mcolonna <marvin@42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/06/27 13:43:21 by mcolonna #+# #+# */
|
||||
/* Updated: 2024/06/28 14:22:50 by mcolonna ### ########.fr */
|
||||
/* Updated: 2024/07/03 14:09:27 by mcolonna ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef VARIABLES_H
|
||||
# define VARIABLES_H
|
||||
|
||||
# define SYMBOL_CHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\
|
||||
_0123456789"
|
||||
|
||||
typedef struct s_variable
|
||||
{
|
||||
const char *name;
|
||||
|
@ -36,4 +39,7 @@ 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);
|
||||
|
||||
// Return true if 'name' is a valid variable name.
|
||||
bool variables_nameisvalid(const char *name);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -6,16 +6,17 @@
|
|||
/* By: jschaft <cecile.schaft@orange.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/06/03 12:02:45 by jschaft #+# #+# */
|
||||
/* Updated: 2024/07/04 11:36:00 by mcolonna ### ########.fr */
|
||||
/* Updated: 2024/07/04 11:56:59 by mcolonna ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "include.h"
|
||||
|
||||
static int unset_builtin(t_env *env, t_call call)
|
||||
static int unset_builtin(t_env *env, t_call call, int std[2])
|
||||
{
|
||||
int i;
|
||||
|
||||
(void)std;
|
||||
i = 0;
|
||||
while (call.argv[++i])
|
||||
variables_unset(env->variables, call.argv[i]);
|
||||
|
@ -39,19 +40,19 @@ bool is_builtin(const char *str)
|
|||
|
||||
// Execute the builtin pwd for the current directory.
|
||||
// Return 0 for the sake of returning something for exec_builtin
|
||||
static int pwd_builtin(t_env *env, t_call call)
|
||||
static int pwd_builtin(t_env *env, t_call call, int std[2])
|
||||
{
|
||||
char *str;
|
||||
|
||||
(void)env;
|
||||
(void)call;
|
||||
str = getcwd(NULL, 0);
|
||||
printf("%s\n", str);
|
||||
print_line(fatal_error, std[1], str);
|
||||
free(str);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int env_builtin(t_env *env, t_call call)
|
||||
static int env_builtin(t_env *env, t_call call, int std[2])
|
||||
{
|
||||
int i;
|
||||
const t_memclass mc = mem_subclass(fatal_error, env->mc_global);
|
||||
|
@ -65,7 +66,7 @@ static int env_builtin(t_env *env, t_call call)
|
|||
i = 0;
|
||||
while (envp[i] != NULL)
|
||||
{
|
||||
printf("%s\n", envp[i]);
|
||||
print_line(fatal_error, std[1], envp[i]);
|
||||
i++;
|
||||
}
|
||||
mem_freeall(mc);
|
||||
|
@ -75,23 +76,23 @@ static int env_builtin(t_env *env, t_call call)
|
|||
// Execute the specified builtin.
|
||||
// The builtin must exist.
|
||||
// Return the error value returned by the builtin.
|
||||
int exec_builtin(t_env *env, t_call call)
|
||||
int exec_builtin(t_env *env, t_call call, int std[2])
|
||||
{
|
||||
if (ft_strncmp(call.program, "cd", 3) == 0)
|
||||
exit (cd_builtin(env, call));
|
||||
return (cd_builtin(env, call, std));
|
||||
if (ft_strncmp(call.program, "exit", 5) == 0)
|
||||
exit (exit_builtin(env, call));
|
||||
return (exit_builtin(env, call, std));
|
||||
if (ft_strncmp(call.program, "export", 7) == 0 && call.argc != 1)
|
||||
exit (export_builtin(env, call));
|
||||
return (export_builtin(env, call, std));
|
||||
if (ft_strncmp(call.program, "export", 7) == 0 && call.argc == 1)
|
||||
return (export_print_builtin(env, call, std));
|
||||
if (ft_strncmp(call.program, "unset", 6) == 0)
|
||||
exit (unset_builtin(env, call));
|
||||
if (ft_strncmp(call.program, "export", 6) == 0 && call.argc == 1)
|
||||
exit (export_print_builtin(env, call));
|
||||
return (unset_builtin(env, call, std));
|
||||
if (ft_strncmp(call.program, "pwd", 4) == 0)
|
||||
exit (pwd_builtin(env, call));
|
||||
return (pwd_builtin(env, call, std));
|
||||
if (ft_strncmp(call.program, "echo", 5) == 0)
|
||||
exit (echo_builtin(env, call));
|
||||
return (echo_builtin(env, call, std));
|
||||
if (ft_strncmp(call.program, "env", 4) == 0)
|
||||
exit (env_builtin(env, call));
|
||||
exit (1);
|
||||
return (env_builtin(env, call, std));
|
||||
return (1);
|
||||
}
|
||||
|
|
|
@ -6,44 +6,17 @@
|
|||
/* By: jschaft <cecile.schaft@orange.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/06/25 13:28:29 by jschaft #+# #+# */
|
||||
/* Updated: 2024/07/01 12:35:28 by jschaft ### ########.fr */
|
||||
/* Updated: 2024/07/03 14:06:04 by mcolonna ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "include.h"
|
||||
|
||||
int export_builtin(t_env *env, t_call call)
|
||||
{
|
||||
int i;
|
||||
char *name;
|
||||
char *value;
|
||||
char **splitted;
|
||||
const t_memclass mc = mem_subclass(fatal_error, env->mc_global);
|
||||
|
||||
i = 0;
|
||||
while (call.argv[++i])
|
||||
{
|
||||
if (char_isin('=', call.argv[i]))
|
||||
{
|
||||
splitted = str_split(fatal_error, mc, call.argv[i], "=");
|
||||
name = splitted[0];
|
||||
value = splitted[1];
|
||||
if (!value)
|
||||
value = "";
|
||||
variables_set(env->variables, name, value);
|
||||
}
|
||||
else
|
||||
name = call.argv[i];
|
||||
variables_export(env->variables, name);
|
||||
}
|
||||
mem_freeall(mc);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int exit_builtin(t_env *env, t_call call)
|
||||
int exit_builtin(t_env *env, t_call call, int std[2])
|
||||
{
|
||||
int r;
|
||||
|
||||
(void)std;
|
||||
if (call.argv[1] && call.argv[2])
|
||||
{
|
||||
print_line(fatal_error, 2, "exit: too many arguments");
|
||||
|
@ -63,7 +36,7 @@ int exit_builtin(t_env *env, t_call call)
|
|||
return (r);
|
||||
}
|
||||
|
||||
int echo_builtin(t_env *env, t_call call)
|
||||
int echo_builtin(t_env *env, t_call call, int std[2])
|
||||
{
|
||||
int i;
|
||||
bool newline;
|
||||
|
@ -78,50 +51,50 @@ int echo_builtin(t_env *env, t_call call)
|
|||
}
|
||||
while (call.argv[i] != NULL)
|
||||
{
|
||||
printf("%s", call.argv[i]);
|
||||
print_str(fatal_error, std[1], call.argv[i]);
|
||||
if (call.argv[i + 1] != NULL)
|
||||
printf(" ");
|
||||
print_str(fatal_error, std[1], " ");
|
||||
i++;
|
||||
}
|
||||
if (newline)
|
||||
printf("\n");
|
||||
print_str(fatal_error, std[1], "\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int go_home(t_env *env, const char dest)
|
||||
static const char *go_home(t_env *env, bool to_old)
|
||||
{
|
||||
if (dest == 'n')
|
||||
return (chdir(variables_get(env->variables, "HOME")), dest);
|
||||
if (dest == '-')
|
||||
return (chdir(variables_get(env->variables, "OLDPWD")));
|
||||
return (0);
|
||||
if (!to_old)
|
||||
return (variables_get(env->variables, "HOME"));
|
||||
else
|
||||
return (variables_get(env->variables, "OLDPWD"));
|
||||
}
|
||||
|
||||
// Execute the builtin cd for the specified path.
|
||||
// Return 0 if success, errno if error.
|
||||
int cd_builtin(t_env *env, t_call call)
|
||||
int cd_builtin(t_env *env, t_call call, int std[2])
|
||||
{
|
||||
int r;
|
||||
int argc;
|
||||
int r;
|
||||
const char *pwd;
|
||||
const bool go_oldpwd = call.argv[1] && str_eq(call.argv[1], "-");
|
||||
|
||||
argc = 0;
|
||||
while (call.argv[argc])
|
||||
argc++;
|
||||
if (argc == 2)
|
||||
r = chdir(call.argv[1]);
|
||||
else if (argc == 1)
|
||||
r = go_home(env, 'n');
|
||||
else if (argc == 2 && ft_strncmp(call.argv[1], "-", 2))
|
||||
r = go_home(env, '-');
|
||||
(void)std;
|
||||
if (call.argc == 1 || go_oldpwd)
|
||||
pwd = go_home(env, go_oldpwd);
|
||||
else if (call.argc == 2)
|
||||
pwd = call.argv[1];
|
||||
else
|
||||
{
|
||||
print_line(fatal_error, 2, "cd: too many arguments");
|
||||
return (1);
|
||||
}
|
||||
return (print_line(fatal_error, 2, "cd: too many arguments"), 1);
|
||||
r = chdir(pwd);
|
||||
if (r)
|
||||
{
|
||||
perror("cd");
|
||||
return (errno);
|
||||
}
|
||||
return (perror("cd"), errno);
|
||||
mem_free((char *)variables_get(env->variables, "OLDPWD"));
|
||||
variables_set(env->variables, "OLDPWD",
|
||||
variables_get(env->variables, "PWD"));
|
||||
pwd = getcwd(NULL, 0);
|
||||
variables_set(env->variables, "PWD",
|
||||
str_dup(fatal_error, env->mc_global, pwd));
|
||||
if (go_oldpwd)
|
||||
print_line(fatal_error, 1, pwd);
|
||||
free((char *)pwd);
|
||||
return (0);
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
/* By: jschaft <cecile.schaft@orange.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/04/24 13:48:00 by jschaft #+# #+# */
|
||||
/* Updated: 2024/07/01 12:36:03 by jschaft ### ########.fr */
|
||||
/* Updated: 2024/07/01 14:32:09 by mcolonna ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
|
@ -35,7 +35,7 @@ static void close_all_pipes(t_exec_command_global *global)
|
|||
|
||||
// Execute a program with specific stdin and stdout:
|
||||
// - inout[0] is stdin
|
||||
// - inout[0] is stdout
|
||||
// - inout[1] is stdout
|
||||
// If call.program doesn't have any '/' in it, find the program in $PATH.
|
||||
// If the program wasn't to found in $PATH, or the fork didn't work,
|
||||
// write the error and return the error status.
|
||||
|
@ -48,9 +48,11 @@ static int execute_call(
|
|||
|
||||
program_path = search_path(global->mc, global->env->variables,
|
||||
call.program);
|
||||
if (!program_path)
|
||||
if (!program_path && !is_builtin(call.program))
|
||||
return (minishell_error(str_join(fatal_error, global->mc,
|
||||
"command not found: ", call.program)), 127);
|
||||
if (is_builtin(call.program))
|
||||
return (exec_builtin(global->env, call, (int *)inout));
|
||||
pid = fork();
|
||||
if (pid < 0)
|
||||
return (minishell_error("errno"), errno);
|
||||
|
@ -60,10 +62,7 @@ static int execute_call(
|
|||
if (dup2(inout[0], 0) < 0 || dup2(inout[1], 1) < 0)
|
||||
return (minishell_error("errno"), errno);
|
||||
close_all_pipes(global);
|
||||
if (is_builtin(call.program))
|
||||
exec_builtin(global->env, call);
|
||||
else
|
||||
execve(program_path, call.argv, envp);
|
||||
execve(program_path, call.argv, envp);
|
||||
return (minishell_error("errno"), errno);
|
||||
}
|
||||
return (0);
|
||||
|
@ -115,6 +114,7 @@ int execute_command(t_env *env, t_command command)
|
|||
int r;
|
||||
int wstatus;
|
||||
|
||||
wstatus = 0;
|
||||
r = 0;
|
||||
global.mc = env->mc_command;
|
||||
global.nb_calls = 0;
|
||||
|
@ -132,7 +132,7 @@ int execute_command(t_env *env, t_command command)
|
|||
;
|
||||
if (errno != ECHILD)
|
||||
return (minishell_error("errno"), errno);
|
||||
if (!r)
|
||||
if (WEXITSTATUS(wstatus))
|
||||
r = WEXITSTATUS(wstatus);
|
||||
return (r);
|
||||
}
|
||||
|
|
60
src/export_builtin.c
Normal file
60
src/export_builtin.c
Normal file
|
@ -0,0 +1,60 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* export_builtin.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: jschaft <cecile.schaft@orange.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/06/25 13:28:29 by jschaft #+# #+# */
|
||||
/* Updated: 2024/07/03 12:17:03 by mcolonna ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "include.h"
|
||||
|
||||
static bool export_builtin_2(t_env *env, t_memclass mc, char **name,
|
||||
const char *arg)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = -1;
|
||||
while (arg[++i] != '=')
|
||||
;
|
||||
*name = mem_alloc(fatal_error, mc, (i + 1) * sizeof(char));
|
||||
i = -1;
|
||||
while (arg[++i] != '=')
|
||||
(*name)[i] = arg[i];
|
||||
(*name)[i] = '\0';
|
||||
if (!variables_nameisvalid(*name))
|
||||
return (false);
|
||||
variables_set(env->variables, *name, arg + i + 1);
|
||||
return (true);
|
||||
}
|
||||
|
||||
int export_builtin(t_env *env, t_call call, int std[2])
|
||||
{
|
||||
int i;
|
||||
char *name;
|
||||
const t_memclass mc = mem_subclass(fatal_error, env->mc_global);
|
||||
int r;
|
||||
|
||||
(void)std;
|
||||
r = 0;
|
||||
i = 0;
|
||||
while (call.argv[++i])
|
||||
{
|
||||
if (char_isin('=', call.argv[i]) && export_builtin_2(
|
||||
env, mc, &name, call.argv[i]));
|
||||
else if (variables_nameisvalid(call.argv[i]))
|
||||
name = call.argv[i];
|
||||
else
|
||||
{
|
||||
print_line(fatal_error, 2, "builtin: bad variable name");
|
||||
r = 1;
|
||||
continue ;
|
||||
}
|
||||
variables_export(env->variables, name);
|
||||
}
|
||||
mem_freeall(mc);
|
||||
return (r);
|
||||
}
|
|
@ -6,13 +6,13 @@
|
|||
/* By: jschaft <cecile.schaft@orange.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/07/03 18:57:19 by jschaft #+# #+# */
|
||||
/* Updated: 2024/07/04 11:50:07 by mcolonna ### ########.fr */
|
||||
/* Updated: 2024/07/04 11:58:06 by mcolonna ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "include.h"
|
||||
|
||||
int export_print_builtin(t_env *env, t_call call)
|
||||
int export_print_builtin(t_env *env, t_call call, int std[2])
|
||||
{
|
||||
int i;
|
||||
int i2;
|
||||
|
@ -26,22 +26,22 @@ int export_print_builtin(t_env *env, t_call call)
|
|||
while (envp[i])
|
||||
{
|
||||
i2 = 0;
|
||||
print_str(fatal_error, 1, "declare -x ");
|
||||
print_str(fatal_error, std[1], "declare -x ");
|
||||
while (envp[i][i2] != '=')
|
||||
{
|
||||
c[0] = envp[i][i2];
|
||||
print_str(fatal_error, 1, c);
|
||||
print_str(fatal_error, std[1], c);
|
||||
i2++;
|
||||
}
|
||||
print_str(fatal_error, 1, "=\"");
|
||||
print_str(fatal_error, std[1], "=\"");
|
||||
i2++;
|
||||
while (envp[i][i2])
|
||||
{
|
||||
c[0] = envp[i][i2];
|
||||
print_str(fatal_error, 1, c);
|
||||
print_str(fatal_error, std[1], c);
|
||||
i2++;
|
||||
}
|
||||
print_str(fatal_error, 1, "\"\n");
|
||||
print_str(fatal_error, std[1], "\"\n");
|
||||
i++;
|
||||
}
|
||||
return (0);
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
/* By: mcolonna <marvin@42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/04/24 13:47:40 by mcolonna #+# #+# */
|
||||
/* Updated: 2024/06/27 14:32:37 by mcolonna ### ########.fr */
|
||||
/* Updated: 2024/07/03 12:08:12 by mcolonna ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
|
@ -52,10 +52,11 @@ static void read_string_noquote(t_parsing_args *args, const char **dest,
|
|||
const char *stop_charset)
|
||||
{
|
||||
const char *real_stop_charset
|
||||
= str_join(fatal_error, args->mc, stop_charset, "$");
|
||||
= str_join(fatal_error, args->mc, stop_charset, "$\"'");
|
||||
|
||||
while (stream_read(&args->stream)
|
||||
&& !char_isin(stream_read(&args->stream), stop_charset))
|
||||
&& !char_isin(stream_read(&args->stream), stop_charset)
|
||||
&& !char_isin(stream_read(&args->stream), "\"'"))
|
||||
{
|
||||
read_until(args, dest, real_stop_charset);
|
||||
if (stream_read(&args->stream) == '$')
|
||||
|
@ -117,10 +118,7 @@ static bool read_string_doublequote(t_parsing_args *args, const char **dest)
|
|||
}
|
||||
|
||||
// Read the string, stop if the char is in stop_charset.
|
||||
// Possible syntaxes:
|
||||
// - /[^(stop_charset)]+/
|
||||
// - /'.*'/
|
||||
// - /".*"/
|
||||
// Syntax: /([^{stop_charset}]|'.*'|".*")+/
|
||||
// Change args->r.error and return NULL if error.
|
||||
const char *read_string(t_parsing_args *args, const char *stop_charset)
|
||||
{
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
/* By: mcolonna <marvin@42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/04/24 13:47:40 by mcolonna #+# #+# */
|
||||
/* Updated: 2024/06/27 14:47:14 by mcolonna ### ########.fr */
|
||||
/* Updated: 2024/07/03 11:33:12 by mcolonna ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
|
@ -15,18 +15,16 @@
|
|||
|
||||
# include "include.h"
|
||||
|
||||
# define SYMBOL_CHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_"
|
||||
|
||||
// Global variables for all the parsing functions
|
||||
typedef struct s_parsing_args
|
||||
{
|
||||
t_memclass mc; // mc freed given to parse_command
|
||||
t_command r; // t_command that parse_command will return
|
||||
t_stream stream; // stream reading the command string
|
||||
t_list calls; // list of calls
|
||||
bool got_first_call; // already got at least the first program call?
|
||||
const char *heredoc; // EOF line for heredoc. NULL if no heredoc
|
||||
t_list *variables; // list of current variables
|
||||
t_memclass mc;
|
||||
t_command r;
|
||||
t_stream stream;
|
||||
t_list calls;
|
||||
bool got_first_call;
|
||||
const char *heredoc;
|
||||
t_list *variables;
|
||||
t_env *env;
|
||||
} t_parsing_args;
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
/* By: mcolonna <marvin@42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/04/24 13:47:40 by mcolonna #+# #+# */
|
||||
/* Updated: 2024/06/28 14:33:14 by mcolonna ### ########.fr */
|
||||
/* Updated: 2024/07/01 13:38:03 by mcolonna ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
|
@ -15,8 +15,10 @@
|
|||
|
||||
void variables_set(t_list *variables, const char *name, const char *value)
|
||||
{
|
||||
variables_find(variables, name)->value = (
|
||||
str_dup(fatal_error, variables->mc, value));
|
||||
t_variable *var;
|
||||
|
||||
var = variables_find(variables, name);
|
||||
var->value = str_dup(fatal_error, variables->mc, value);
|
||||
}
|
||||
|
||||
const char *variables_get(t_list *variables, const char *name)
|
||||
|
|
24
src/variables2.c
Normal file
24
src/variables2.c
Normal file
|
@ -0,0 +1,24 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* variables2.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: mcolonna <marvin@42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/07/02 15:39:55 by mcolonna #+# #+# */
|
||||
/* Updated: 2024/07/02 15:41:42 by mcolonna ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "include.h"
|
||||
|
||||
bool variables_nameisvalid(const char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = -1;
|
||||
while (name[++i])
|
||||
if (!char_isin(name[i], SYMBOL_CHARS))
|
||||
return (false);
|
||||
return (true);
|
||||
}
|
Loading…
Add table
Reference in a new issue