Compare commits

...

15 commits
TRY0 ... main

Author SHA1 Message Date
164552cf0c Update README.md 2025-07-31 15:56:26 +00:00
mcolonna
c34c1b1997 add README.md 2025-07-30 20:10:02 +02:00
mcolonna
89dae11aa1 fix: link readline library 2025-07-30 17:28:45 +02:00
mcolonna
254bee62c7 fixes 2024-07-04 13:50:43 +02:00
mcolonna
6184e4e982 norm 2024-07-04 12:19:49 +02:00
mcolonna
01722c4e21 merge 2024-07-04 12:02:56 +02:00
mcolonna
b6aed6ad78 things 2024-07-04 11:52:22 +02:00
joris schaft
668bd06c17 [FIX] export without arg 2024-07-03 19:01:35 +02:00
mcolonna
75150f95dd norm 2024-07-03 14:10:44 +02:00
mcolonna
6862a1913b fix: export builtin and other things *
fix: parse_command: syntaxes like: "hello"'hello'hello
fix: export builtin: "NAME=VALUE" syntax
fix: variables can contain digits
add: variables_nameisvalid()
change: dev/valgrind.sh
2024-07-03 12:18:16 +02:00
mcolonna
b0aa3da8ce merge cd builtin 2024-07-02 11:45:31 +02:00
mcolonna
7d38a40717 fix: several builtins *
With the fork, the builtins didn't have access to the parent process values.
2024-07-01 14:33:38 +02:00
mcolonna
c637b5f382 fix: builtins and pipes *
also: dev: add dev/nocluster.sh
2024-07-01 13:56:19 +02:00
mcolonna
147743058d norm 2024-07-01 13:39:45 +02:00
joris schaft
5b313a1f5c [ADD] helo 2024-07-01 12:36:35 +02:00
18 changed files with 307 additions and 139 deletions

View file

@ -5,19 +5,20 @@ SRCS = src/
# include directory
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 variables_utils
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 \
export_builtin variables2
# directories to 'make'
LIBRARIES = libtf libft
# .a files to include
LIBRARIES_FILES = libtf/libtf.a libft/libft.a
# to use with the flags -L and -l
LIBRARIES_LINK =
LIBRARIES_LINK = readline
# 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)

37
README.md Normal file
View file

@ -0,0 +1,37 @@
# minishell
the result of a group project at 42 school, made by me and [BgNounours](https://github.com/BgNounours).
it's a very basic shell like sh or bash. it is not POSIX.
it supports:
- `>`, `<`, `>>`, `<<` redirections
- `|` pipes
- environment variables and $?
- some built-in commands
## compile and run
this project is for linux (it may also work on macOS i have no idea).
1. in your terminal, run `make -v`.
if you have a `command not found` error or equivalent, you will need to install `make`. on ubuntu / debian, run:
```sh
$ sudo apt install make
```
2. clone the repository and cd inside it:
```sh
$ git clone https://gitea.zaclys.com/frzysk/42_minishell
$ cd 42_minishell
```
3. build:
```sh
$ make
```
4. run:
```
$ ./minishell
```

3
dev/nocluster.sh Executable file
View file

@ -0,0 +1,3 @@
# call this file with "source dev/nocluster.sh"
alias makee="make MORE_FLAGS=\"-lreadline\""

View file

@ -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

View file

@ -6,7 +6,7 @@
/* By: jschaft <cecile.schaft@orange.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/23 14:15:12 by mcolonna #+# #+# */
/* Updated: 2024/06/28 15:26:29 by mcolonna ### ########.fr */
/* Updated: 2024/07/04 12:02:43 by mcolonna ### ########.fr */
/* */
/* ************************************************************************** */
@ -15,22 +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 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

View file

@ -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

View file

@ -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.

View file

@ -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

View file

@ -6,16 +6,17 @@
/* By: jschaft <cecile.schaft@orange.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/06/03 12:02:45 by jschaft #+# #+# */
/* Updated: 2024/06/28 15:30:51 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,23 +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;
if (call.argv[1])
{
print_line(fatal_error, 2, "too many arguments");
return (1);
}
(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);
@ -69,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);
@ -79,21 +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)
return (cd_builtin(env, call));
return (cd_builtin(env, call, std));
if (ft_strncmp(call.program, "exit", 5) == 0)
return (exit_builtin(env, call));
if (ft_strncmp(call.program, "export", 7) == 0)
return (export_builtin(env, call));
return (exit_builtin(env, call, std));
if (ft_strncmp(call.program, "export", 7) == 0 && call.argc != 1)
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)
return (unset_builtin(env, call));
return (unset_builtin(env, call, std));
if (ft_strncmp(call.program, "pwd", 4) == 0)
return (pwd_builtin(env, call));
return (pwd_builtin(env, call, std));
if (ft_strncmp(call.program, "echo", 5) == 0)
return (echo_builtin(env, call));
return (echo_builtin(env, call, std));
if (ft_strncmp(call.program, "env", 4) == 0)
return (env_builtin(env, call));
return (env_builtin(env, call, std));
return (1);
}

View file

@ -6,44 +6,17 @@
/* By: jschaft <cecile.schaft@orange.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/06/25 13:28:29 by jschaft #+# #+# */
/* Updated: 2024/06/28 15:30:55 by mcolonna ### ########.fr */
/* Updated: 2024/07/04 13:35:21 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,44 +51,51 @@ 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)
static const char *go_home(t_env *env, bool to_old)
{
return (chdir(variables_get(env->variables, "HOME")));
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;
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);
(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_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);
}

View file

@ -6,7 +6,7 @@
/* By: jschaft <cecile.schaft@orange.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/24 13:48:00 by jschaft #+# #+# */
/* Updated: 2024/06/28 16:08:02 by mcolonna ### ########.fr */
/* Updated: 2024/07/01 14:32:09 by mcolonna ### ########.fr */
/* */
/* ************************************************************************** */
@ -35,22 +35,24 @@ 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.
static int execute_call(
t_exec_command_global *global, t_call call, const int inout[2],
char *const envp[])
t_exec_command_global *global, t_call call,
const int inout[2], char *const envp[])
{
pid_t pid;
const char *program_path;
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);
@ -97,9 +99,6 @@ static int exec_each_call(t_exec_command_global *global,
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,
variables_envp(env->variables, mc));
mem_freeall(mc);
@ -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
View 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);
}

View file

@ -0,0 +1,54 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* export_print_builtin.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jschaft <cecile.schaft@orange.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/07/03 18:57:19 by jschaft #+# #+# */
/* Updated: 2024/07/04 12:19:08 by mcolonna ### ########.fr */
/* */
/* ************************************************************************** */
#include "include.h"
static void export_print_builtin_loop(char *const var, int std[2])
{
int i;
char c[2];
c[1] = '\0';
i = 0;
print_str(fatal_error, std[1], "declare -x ");
while (var[i] != '=')
{
c[0] = var[i];
print_str(fatal_error, std[1], c);
i++;
}
print_str(fatal_error, std[1], "=\"");
i++;
while (var[i])
{
c[0] = var[i];
print_str(fatal_error, std[1], c);
i++;
}
print_str(fatal_error, std[1], "\"\n");
}
int export_print_builtin(t_env *env, t_call call, int std[2])
{
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])
{
export_print_builtin_loop(envp[i], std);
i++;
}
return (0);
}

View file

@ -6,7 +6,7 @@
/* By: mcolonna <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/24 13:47:40 by mcolonna #+# #+# */
/* Updated: 2024/06/28 14:10:53 by mcolonna ### ########.fr */
/* Updated: 2024/07/04 13:49:57 by mcolonna ### ########.fr */
/* */
/* ************************************************************************** */
@ -62,7 +62,7 @@ static bool parse_variable_set_command(
read_only(args, &name, SYMBOL_CHARS);
if (str_len(name) == 0 || stream_pop(&args->stream) != '=')
return (false);
value = read_string(args, "<>|/");
value = read_string(args, "<>|");
if (args->r.error)
return (false);
if (!value)

View file

@ -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)
{

View file

@ -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;

View file

@ -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
View 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);
}