diff --git a/.tmp b/.tmp deleted file mode 100644 index e69de29..0000000 diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index d96f3b9..0000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "version": "0.2.0", - "configurations": [ - { - "type": "lldb", - "request": "launch", - "name": "Debug", - "program": "${workspaceFolder}/", - "args": [], - "cwd": "${workspaceFolder}" - }, - { - "name": "C/C++: clang build and debug active file", - "type": "cppdbg", - "request": "launch", - "program": "${fileDirname}/${fileBasenameNoExtension}", - "args": [], - "stopAtEntry": false, - "cwd": "${fileDirname}", - "environment": [], - "externalConsole": false, - "MIMode": "lldb", - "preLaunchTask": "C/C++: clang build active file" - }, - { - "name": "C/C++: gcc build and debug active file", - "type": "cppdbg", - "request": "launch", - "program": "${fileDirname}/${fileBasenameNoExtension}", - "args": [], - "stopAtEntry": false, - "cwd": "${fileDirname}", - "environment": [], - "externalConsole": false, - "MIMode": "lldb", - "preLaunchTask": "C/C++: gcc build active file" - } - ] -} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 53813ab..ade968b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,10 +1,11 @@ { "files.associations": { - "__functional_03": "c", + "array": "c", "functional": "c", - "libft.h": "c", - "__node_handle": "c", - "algorithm": "c", - "locale": "c" + "istream": "c", + "ostream": "c", + "tuple": "c", + "type_traits": "c", + "utility": "c" } } \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json index e679af0..49b20e2 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -2,7 +2,7 @@ "tasks": [ { "type": "cppbuild", - "label": "C/C++: gcc build active file", + "label": "C/C++: gcc compilar archivo activo", "command": "/usr/bin/gcc", "args": [ "-fdiagnostics-color=always", @@ -21,28 +21,7 @@ "kind": "build", "isDefault": true }, - "detail": "Task generated by Debugger." - }, - { - "type": "cppbuild", - "label": "C/C++: clang build active file", - "command": "/usr/bin/clang", - "args": [ - "-fcolor-diagnostics", - "-fansi-escape-codes", - "-g", - "${file}", - "-o", - "${fileDirname}/${fileBasenameNoExtension}" - ], - "options": { - "cwd": "${fileDirname}" - }, - "problemMatcher": [ - "$gcc" - ], - "group": "build", - "detail": "Task generated by Debugger." + "detail": "Tarea generada por el depurador." } ], "version": "2.0.0" diff --git a/Makefile b/Makefile index dd065c6..da12d1c 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,5 @@ NAME = minishell +NAMEBONUS = minishell_bonus LIBNAME = libft.a SRC = ./src/splitstr/split.c \ ./src/splitstr/split_utils.c \ @@ -21,8 +22,31 @@ SRC = ./src/splitstr/split.c \ ./src/builtins/bt_unset.c \ ./src/builtins/btmanager.c \ ./src/builtins/bt_exit.c +SRCBONUS = ./src/splitstr/split_bonus.c \ + ./src/splitstr/split_utils.c \ + ./src/splitstr/clean_quotes.c \ + ./src/splitstr/check_var.c \ + ./src/splitstr/correc_special.c \ + ./src/parser/parser_bonus.c \ + ./src/parser/executor_bonus.c \ + ./src/parser/heredoc_bonus.c \ + ./src/parser/getpaths_bonus.c \ + ./src/parser/parser_util_bonus.c \ + ./src/parser/parser_util2_bonus.c \ + ./src/parser/wildcard_bonus.c \ + ./src/terminal/terminal_bonus.c \ + ./src/main.c \ + ./src/error/error.c \ + ./src/envutils/envcp.c \ + ./src/builtins/bt_cd.c \ + ./src/builtins/bt_env_pwd_echo.c \ + ./src/builtins/bt_export.c \ + ./src/builtins/bt_unset.c \ + ./src/builtins/btmanager.c \ + ./src/builtins/bt_exit.c OBJ = $(SRC:.c=.o) +OBJBONUS = $(SRCBONUS:.c=.o) FLAGS = -Wall -Wextra -Werror -g3 -fsanitize=address READFLAG = -lreadline -L/Users/$(USER)/.brew/opt/readline/lib @@ -39,6 +63,11 @@ $(NAME): $(OBJ) $(LIBNAME) @gcc $(FLAGS) $(OBJ) $(LIBNAME) $(READFLAG) -o $(NAME) @echo $(GREEN)"- Compiled -"$(NONE) +bonus: $(OBJBONUS) $(LIBNAME) + @echo $(CURSIVE)$(GRAY) " - Compiling $(NAMEBONUS)..." $(NONE) + @gcc $(FLAGS) $(OBJBONUS) $(LIBNAME) $(READFLAG) -o $(NAMEBONUS) + @echo $(GREEN)"- Compiled -"$(NONE) + $(LIBNAME): @echo $(CURSIVE)$(GRAY) " - Compiling LIBFT $(LIBNAME)..." $(NONE) @$(MAKE) -C ./libft all @@ -51,11 +80,11 @@ $(LIBNAME): clean: @echo $(CURSIVE)$(GRAY) " - Removing object files..." $(NONE) @$(MAKE) -C ./libft clean - @rm -rf $(OBJ) + @rm -rf $(OBJ) $(OBJBONUS) fclean: clean @echo $(CURSIVE)$(GRAY) " - Removing $(NAME) And $(LIBNAME)..." $(NONE) @$(MAKE) -C ./libft fclean - @rm -rf $(NAME) $(LIBNAME) + @rm -rf $(NAME) $(NAMEBONUS) $(LIBNAME) re: fclean all \ No newline at end of file diff --git a/docs/Bash Reference Manual.pdf b/docs/Bash Reference Manual.pdf deleted file mode 100644 index 727811d..0000000 Binary files a/docs/Bash Reference Manual.pdf and /dev/null differ diff --git a/docs/Chapter5-WritingYourOwnShell.pdf b/docs/Chapter5-WritingYourOwnShell.pdf deleted file mode 100644 index 9f4fc00..0000000 Binary files a/docs/Chapter5-WritingYourOwnShell.pdf and /dev/null differ diff --git a/docs/README.md b/docs/README.md deleted file mode 100644 index 5d566d7..0000000 --- a/docs/README.md +++ /dev/null @@ -1,212 +0,0 @@ -https://m4nnb3ll.medium.com/minishell-building-a-mini-bash-a-42-project-b55a10598218 - -https://www.cs.purdue.edu/homes/grr/SystemsProgrammingBook/Book/Chapter5-WritingYourOwnShell.pdf - -https://github.com/Swoorup/mysh - -https://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html - -https://github.com/madebypixel02/minishell/blob/main/README.md - -https://www.youtube.com/watch?v=4jYFqFsu03A&list=PLGU1kcPKHMKj5yA0RPb5AK4QAhexmQwrW&index=7 - - - -En makefile - - -L/Users/$(USER)/.brew/opt/readline/lib -I/Users/$(USER)/.brew/opt/readline/include - -Comp - - comp -lreadline terminal.c libft.a -L/Users/$USER/.brew/opt/readline/lib -I/Users/$USER/.brew/opt/readline/include && ./a.out - -Readline Library - - https://tiswww.case.edu/php/chet/readline/readline.html - -Para compilar readline - - -L/Users/$USER/.brew/opt/readline/lib - -I/Users/$USER/.brew/opt/readline/include - - - - -suprimir leaks readline - - valgrind --suppressions=readline.supp --leak-check=full --show-leak-kinds=all ./minishell - - ------- - -- [ ] Compile - - - USE make -n to see if compilation use -Wall -Wextra -Werror if not use invalid compilation flags - - minishell Compile without errors if not use flags - - makefile must not re-link - -- [ ] Simple Command & global - - - Execute a simple command with an absolute path like /bin/ls or any other command without options - - How many global variables? why? Give a concrete example of why it feels mandatory or logical. - - Test an empty command. - - Test only spaces or tabs. - - if something crashes use the crash flag. - - if something is not working use the incomplete work flag. - -- [ ] Arguments & history - - - Execute a simple command with an absolute path like /bin/ls or any other command with arguments but without - quotes and double quotes - - Repeat multiple times with different commands and arguments - - if something crashes use the crash flag. - - if something is not working use the incomplete work flag. - - -- [ ] echo - - - Execute the echo command with or without arguments or -n - - Repeat multiple times with different arguments - - if something crashes use the crash flag. - - if something is not working use the incomplete work flag. - - -- [ ] exit - - - Execute exit command with or without arguments - - Repeat multiple times with different arguments - - Don't forget to relaunch the minishell - - if something crashes use the crash flag. - - if something is not working use the incomplete work flag - -- [ ] Return value of a process - - - Execute a simple command with an absolute path like /bin/ls or any other command with arguments but without - quotes and double quotes then execute echo $? - - Check the printed value. You can repeat the same in bash and compare it. - - Repeat multiple times with different commands and arguments, use some failing commands like '/bin/ls - filethatdoesntexist' - - anything like expr $? + $? - - if something crashes use the crash flag. - - if something is not working use the incomplete work flag. - - -- [ ] Signals - - - Try ctrl-C in an empty prompt should show a new line with a new prompt - - Try ctrl-\ in an empty prompt should not do anything - - Try ctrl-D in an empty prompt should quit minishell --> RELAUNCH! - - Try ctrl-C in a prompt after you wrote some stuff should show a new line with a new prompt - - Try ctrl-D in a prompt after you wrote some stuff should not do anything - - Try ctrl-\ in a prompt after you wrote some stuff should quit minishell --> RELAUNCH! - - Try ctrl-C after running a blocking command like cat or grep without arguments - - Try ctrl-\ after running a blocking command like cat or grep without arguments - - Try ctrl-D after running a blocking command like cat or grep without arguments - - Repeat multiple times with different commands - - if something crashes use the crash flag. - - if something is not working use the incomplete work flag. - - -- [ ] Double Quotes - - - Execute commands with simple quotes as an argument - - Try empty arguments - - Try environment variables, whitespaces, pipes, redirection in the simple quotes - - echo '$USER' must print $USER - - Nothing should be interprated - -- [ ] env - - - Check if env shows you the current environment variables - -- [ ] export - - - Export environment variables, create new ones, and replace old ones - - Check them with env - -- [ ] unset - - - Export environment variables, create new ones, and replace old ones - - Use unset to remove some of them - - Check the result with env - - -- [ ] cd - - - Use the command cd to move the working directory and check if you are in the right directory with /bin/ls - - Repeat multiple times with working and not working cd - - try '.' '..' as arguments too - - -- [ ] pwd - - - Use the command pwd - - Repeat multiple times in multiple directories - - -- [ ] Relative Path - - - Execute commands but this time use a relative path - - Repeat multiple times in multiple directories with a complex relative path (lots of ..) - - Execute commands but this time without any path. (ls, wc, awk etc...) - - Unset the $PATH and check if it is not working anymore - - Set the $PATH to a multiple directory value (directory1:directory2) and check that directories are checked in order - from left to right - -- [ ] Redirection - - - Execute commands with redirections < and/or > - - Repeat multiple times with different commands and arguments and sometimes change > with >> - - Check if multiple of the same redirections fail - - Test << redirection (it doesn't need to update history). - - -- [ ] Pipes - - - Execute commands with pipes like 'cat file | grep bla | more' - - Repeat multiple times with different commands and arguments - - Try some failing commands like 'ls filethatdoesntexist | grep bla | more' - - Try to mix pipes and redirections. - - -- [ ] Go Crazy and history - - - type a command line then use ctrl-C then press enter the buffer should be clean and nothing try to execute. - - Can we navigate through history with up and down and retry some command - - Execute commands that should not work like 'dsbksdgbksdghsd' and check if the shell doesn't crash and prints an - error - - Try to execute a long command with a ton of arguments - - Have fun with that beautiful minishell and enjoy it - - -- [ ] Environment Variables - - - Execute echo with some $ variables as argumentss - - Check that $ is interprated as an environment variable - - Check that double quotes interpolate $ - - Check that $USER exist or set it. - - echo "$USER" should print the value of $USER - -BONUS - -- [ ] And, Or - - - Use &&, || and parenthesis with commands and check if it works as bash - - -- [ ] WildCard - - - Use wildcards in arguments for the local directory. - - -- [ ] Surprise (or not...) - - - set USER environment variable. - - Test echo "'$USER'" this should print 'USER_VALUE' - - Test echo '"$USER"' this should print "$USER" - - - - -![144017004-aa68e8d7-5da7-4ece-afc6-b8ab100113df](https://github.com/tentaclepurple/Minishell/assets/116112114/c8a7150d-eb99-4cf0-bfec-85792c8dd939) -![144017016-ef2bb606-c301-42c6-88f1-8ed4339d22cd](https://github.com/tentaclepurple/Minishell/assets/116112114/c6bc01d7-6262-49c3-b946-6104c2089dab) diff --git a/docs/en.subject.pdf b/docs/en.subject.pdf deleted file mode 100644 index d98b98e..0000000 Binary files a/docs/en.subject.pdf and /dev/null differ diff --git a/docs/lvl3_Correcction_minishell.pdf b/docs/lvl3_Correcction_minishell.pdf deleted file mode 100644 index 5c49d50..0000000 Binary files a/docs/lvl3_Correcction_minishell.pdf and /dev/null differ diff --git a/inc/parse.h b/inc/parse.h index be2efb0..f6db88c 100644 --- a/inc/parse.h +++ b/inc/parse.h @@ -3,17 +3,17 @@ /* ::: :::::::: */ /* parse.h :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: jzubizar +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/10/03 17:18:15 by jzubizar #+# #+# */ -/* Updated: 2023/11/02 12:14:11 by jzubizar ### ########.fr */ +/* Updated: 2023/11/14 10:16:36 by codespace ### ########.fr */ /* */ /* ************************************************************************** */ #ifndef PARSE_H # define PARSE_H -# include"../libft/libft.h" +# include "../libft/libft.h" # include # include # include @@ -99,7 +99,7 @@ int ft_check_var(char **str, char **env); char **ft_correc_special(char **str, char *spec); int ft_clean_quotes(char **str); -//Spllit +//Split int ft_str_chlen(char const *s, char c); int ft_nbr_wrd(char const *s, char c); char *ft_fill_word(char *wrd, char *str, int len); @@ -107,13 +107,14 @@ void ft_mv_in_quotes(char const *s, unsigned int *i); char *ft_correct_str(char *str); char **ft_split_str(char const *s, char c); void ft_free_split(char **str); - char **ft_inout_file(t_px *node, char **str); int ft_is_cm(char *str, t_px *node); int ft_num_args(char **str); - void ft_handle_client(int sig); void ft_2nd_handler(int sig); +size_t ft_strlen_var(const char *s, int quote); +int ft_len_var_cond(char *env, char *str, int index, int quote); +char *ft_expand_concat(char *env, int len, char *res, char ch); /* parse @@ -150,6 +151,7 @@ void ft_alloc_fd(t_px *px); void ft_free_fd(t_px *px); void write_here_doc_tmp(t_px *px); void ft_getline_aux(char c, char **str); +void pipex_p_aux(t_px *px, int i, pid_t pid); /* terminal.c @@ -158,6 +160,9 @@ int check_no_env(char **env); void terminal(t_info *info); int check_env_and_vars(char **env); void terminal_options(char *input); +void ft_open_outfiles(t_px *nodes); +int ft_lines2(char *str, t_info *info, char ***res); +void ft_open_outfiles(t_px *nodes); /* envutils @@ -167,6 +172,7 @@ char **add_var(char **env, char *var); char **del_var_aux(int found, char **env, char **envcpy); char **del_var(char **env, char *var); int found_in_env(char *var, char **env, char **path); +int ft_is_dir(const char *name); /* bt_cd.c @@ -175,6 +181,7 @@ char **ft_cd(t_px *px); char **ft_cd_update_env(char **env, char *path); void ft_cd_home(t_px *px, char ***envcpy); void ft_cd_oldpwd(t_px *px, char ***envcpy); +void ft_cd_tilde(t_px *px, char ***envcpy); /* bt_env_pwd_echo.c @@ -208,17 +215,6 @@ bt_exit.c */ int ft_bt_exit(t_px *node); -/* -wildcard - */ -void fill_exp_cmdargs(char *pattern, char ***exp_cmdargs); -void ft_wildcard(char ***cmdargs); -int ft_matlen(char **mat); -int count_dir(void); -char **create_exp_cmdargs(char **cmdargs, int *size); -int find_wild_match(char *pattern, char *str); -char **trim_excess(char **exp, int size); - int g_stat; #endif \ No newline at end of file diff --git a/inc/parse_bonus.h b/inc/parse_bonus.h new file mode 100644 index 0000000..4e557dc --- /dev/null +++ b/inc/parse_bonus.h @@ -0,0 +1,245 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* parse_bonus.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: codespace +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/10/03 17:18:15 by jzubizar #+# #+# */ +/* Updated: 2023/11/14 10:16:23 by codespace ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef PARSE_H +# define PARSE_H + +# include "../libft/libft.h" +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include + +/*# include "../colors.h" +# include "../pipex.h" +# include "../../terminal.h"*/ + +# define RED "\033[0;31m" +# define GREEN "\033[0;32m" +# define GREENB "\033[32;1m" +# define YELLOW "\033[0;33m" +# define BLUE "\033[0;34m" +# define BLUEB "\033[34;1m" +# define PURPLE "\033[0;35m" +# define PURPLEB "\033[35;1m" +# define CYAN "\033[0;36m" +# define BOLD "\033[0;1m" +# define X "\033[0;0m" + +typedef enum e_mini_error +{ + QUOTE = 1, + NDIR = 2, + NPERM = 3, + NCMD = 6, + DUPERR = 7, + FORKERR = 8, + PIPERR = 9, + SYNERR = 10, + MEM = 11, + IS_DIR = 12, + NOT_DIR = 13, + NODE = 14, + HOMSET, + OPWDSET +} t_mini_error; + +typedef enum s_type +{ + NONE=0, + CMD=1, + BIp, + BIc, + T_PIPE, + T_AND, + T_OR, + L_PAR, + R_PAR +} t_type; + +typedef struct s_info +{ + int cmd_amount; + int **fd; + char **envcp; + char *homepath; +} t_info; + +typedef struct s_px +{ + t_type type; + char *path; + char **full_cmd; + int in_flag; + int out_flag; + char *infile; + char *outfile; + char *limit; + t_info *info; + int cmd_num; + int cmd_real_num; +} t_px; + +int ft_check_var(char **str, char **env); +char **ft_correc_special(char **str, char *spec); +int ft_clean_quotes(char **str); + +//Spllit +int ft_str_chlen(char const *s, char c); +int ft_nbr_wrd(char const *s, char c); +char *ft_fill_word(char *wrd, char *str, int len); +void ft_mv_in_quotes(char const *s, unsigned int *i); +char *ft_correct_str(char *str); +char **ft_split_str(char const *s, char c); +void ft_free_split(char **str); +char **ft_inout_file(t_px *node, char **str); +int ft_is_cm(char *str, t_px *node); +int ft_num_args(char **str); +void ft_handle_client(int sig); +void ft_2nd_handler(int sig); +size_t ft_strlen_var(const char *s, int quote); +int ft_len_var_cond(char *env, char *str, int index, int quote); +char *ft_expand_concat(char *env, int len, char *res, char ch); + +/* +parse +*/ +t_px *ft_parse(char **str, t_info *info); +int ft_node_quant(char **str); +void ft_free_nodes(t_px *nodes); +char **ft_parse_loop(t_px *node, char **str, char **env); +t_px *ft_init_nodes(t_info *info); +int ft_check_nodes(t_px *nodes); +void ft_stat_signaled(void); +//Bonus +void ft_num_node_cmd(t_px *nodes); + +/* +ERROR.C +*/ +void *ft_error(int err_type, char *param, int err); +void *ft_bt_error(int err_type, char *param, int err); + +/* +executor_bonus.c +*/ +void pipex(t_px *px); +int pipex_p(t_px *px); +void ft_output_redirect(t_px *px); +void ft_input_redirect(t_px *px); +void ft_fd_pipes(t_px *px, int n); +void ft_child(t_px *px, int n); +char *get_cmd_or_cmdpath(char **env, char *str); +char *ft_getline(int fd); +char **get_path(char **env); +int check_slash(char *str); +void ft_fd_close(t_px *px, int j); +void ft_alloc_fd(t_px *px); +void ft_free_fd(t_px *px); +void write_here_doc_tmp(t_px *px); +void ft_getline_aux(char c, char **str); + +void pipex_p_aux(t_px *px, int i, pid_t pid); + +/* +terminal.c +*/ +int check_no_env(char **env); +void terminal(t_info *info); +int check_env_and_vars(char **env); +void terminal_options(char *input); + +void ft_open_outfiles(t_px *nodes); +int ft_lines2(char *str, t_info *info, char ***res); +void ft_open_outfiles(t_px *nodes); + +/* +envutils +*/ +char **ft_env_cpy(char **env); +char **add_var(char **env, char *var); +char **del_var_aux(int found, char **env, char **envcpy); +char **del_var(char **env, char *var); +int found_in_env(char *var, char **env, char **path); + +int ft_is_dir(const char *name); + +/* +bt_cd.c +*/ +char **ft_cd(t_px *px); +char **ft_cd_update_env(char **env, char *path); +void ft_cd_home(t_px *px, char ***envcpy); +void ft_cd_oldpwd(t_px *px, char ***envcpy); + +void ft_cd_tilde(t_px *px, char ***envcpy); + +/* +bt_env_pwd_echo.c +*/ +void ft_pwd(void); +void ft_echo(t_px *px); +void ft_env(char **env); + +/* +unset.c +*/ +char **ft_unset(t_px *px); + +/* +export.c +*/ +int find_equal(char *var, int *found); +void export_declare(char **env); +char **ft_export_aux_del(char **env, char **cmdargs, int i, int found); +char **ft_export_aux(char **env, char **cmdargs); +char **ft_export(char **env, char **cmdargs); + +/* +ft_manag.c +*/ +int ft_execbi_parent(t_px *px); +void ft_execbi_child(t_px *px); + +/* +bt_exit.c +*/ +int ft_bt_exit(t_px *node); + +/* +wildcard + */ +void fill_exp_cmdargs(char *pattern, char ***exp_cmdargs, int *j); +void ft_wildcard(t_px *node); +int ft_matlen(char **mat); +int count_dir(void); +char **create_exp_cmdargs(char **cmdargs, int *size); +int find_wild_match(char *pattern, char *str); +char **trim_excess(char **exp, int size); + +//main.c +void ft_free_info(t_info *info); + +int g_stat; + +#endif \ No newline at end of file diff --git a/oldies/.hola b/oldies/.hola deleted file mode 100644 index e69de29..0000000 diff --git a/oldies/.inv b/oldies/.inv deleted file mode 100644 index e69de29..0000000 diff --git a/oldies/1.txt b/oldies/1.txt deleted file mode 100644 index e69de29..0000000 diff --git a/oldies/a.out b/oldies/a.out deleted file mode 100755 index 9d15e5d..0000000 Binary files a/oldies/a.out and /dev/null differ diff --git a/oldies/a.out.dSYM/Contents/Info.plist b/oldies/a.out.dSYM/Contents/Info.plist deleted file mode 100644 index 3679a65..0000000 --- a/oldies/a.out.dSYM/Contents/Info.plist +++ /dev/null @@ -1,20 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleIdentifier - com.apple.xcode.dsym.a.out - CFBundleInfoDictionaryVersion - 6.0 - CFBundlePackageType - dSYM - CFBundleSignature - ???? - CFBundleShortVersionString - 1.0 - CFBundleVersion - 1 - - diff --git a/oldies/a.out.dSYM/Contents/Resources/DWARF/a.out b/oldies/a.out.dSYM/Contents/Resources/DWARF/a.out deleted file mode 100644 index 484f583..0000000 Binary files a/oldies/a.out.dSYM/Contents/Resources/DWARF/a.out and /dev/null differ diff --git a/oldies/iban.c b/oldies/iban.c deleted file mode 100644 index d91da3d..0000000 --- a/oldies/iban.c +++ /dev/null @@ -1,290 +0,0 @@ - -#include "../../inc/parse.h" - -void ft_fd_close(t_px *px, int j) -{ - int i; - - i = 0; - while (i < j) - { - close(px->info->fd[i][0]); - close(px->info->fd[i][1]); - i++; - } -} - -void ft_alloc_fd(t_px *px) -{ - int i; - - i = 0; - px->info->fd = malloc(sizeof(int *) * (px->info->cmd_amount - 1)); - while (i < px->info->cmd_amount - 1) - { - px->info->fd[i] = malloc(sizeof(int) * 2); - pipe(px->info->fd[i]); - i++; - } -} - -void ft_free_fd(t_px *px) -{ - int i; - - i = 0; - while (i < px->info->cmd_amount - 1) - { - free(px->info->fd[i]); - i++; - } - free(px->info->fd); -} - -void write_here_doc_tmp(t_px *px) -{ - char *line; - char *limit_n; - int fd; - - fd = open(".tmp", O_CREAT | O_WRONLY | O_TRUNC, 0644); - while (1) - { - line = ft_getline(0); - limit_n = ft_strjoin(px->limit, "\n"); - if (ft_strcmp(limit_n, line) == 0) - { - free(limit_n); - break ; - } - free(limit_n); - ft_putstr_fd(line, fd); - free(line); - } - free(line); - close(fd); -} - -char *ft_getline(int fd) -{ - char c; - char *str; - char *tmp; - char *aux; - - str = malloc(1 * sizeof(char)); - str[0] = 0; - while (read(fd, &c, 1) > 0) - { - aux = str; - tmp = malloc(2 * sizeof(char)); - tmp[0] = c; - tmp[1] = 0; - str = ft_strjoin(str, tmp); - free(tmp); - free(aux); - if (c == '\n') - break ; - } - return (str); -} - -/* - if there is more than 1 command, make dups. - cases: - - first cmd: dup2 stdout (if there is no >, >>) - - middle cmd: dup2 stdin & stdout (if there is no >, >> or <, <<) - - last cmd: dup2 stdin (if there is no <, <<) -*/ -void ft_fd_pipes(t_px *px, int n) -{ - - if (n == 0) //first cmd - { - fprintf(stderr, "pipes first cmd\n"); - if (dup2(px->info->fd[n][1], STDOUT_FILENO) < 0) - printf("error dup"); //ft_error_free_exit("dup error 1", NULL, px); - } - else if (n == px->info->cmd_amount - 1 && px->in_flag == 0) //last cmd - { - fprintf(stderr, "pipes last cmd\n"); - if (dup2(px->info->fd[n - 1][0], STDIN_FILENO) < 0) - printf("error dup"); //ft_error_free_exit("dup error 1", NULL, px); - } - else //middle cmd - { - fprintf(stderr, "pipes mid cmd output red flag: %i\n", px->out_flag); - if (px->out_flag == 0) - { - if (dup2(px->info->fd[n][1], STDOUT_FILENO) < 0) - printf("error dup"); //ft_error_free_exit("dup error 1", NULL, px); - } - fprintf(stderr, "pipes mid cmd input red flag: %i\n", px->in_flag); - if (px->in_flag == 0) - { - if (dup2(px->info->fd[n - 1][0], STDIN_FILENO) < 0) - printf("error dup"); //ft_error_free_exit("dup error 1", NULL, px); - } - } - fprintf(stderr, "he pasado por pipes\n"); -} - -/* - dup2 command input: - if n = 1: < (infile) - if n = 2: << (here_doc) -*/ -void ft_input_redirect(t_px *px) -{ - int fd_in; - - fprintf(stderr, "flaginpppp: %i\n", px->in_flag); - if (px->in_flag == 1) - { - fprintf(stderr, "redir <\n"); - fd_in = open(px->infile, O_RDONLY); - if (dup2(fd_in, STDIN_FILENO) < 0) - printf("error dup"); //ft_error_free_exit("dup error 1", NULL, px); - close(fd_in); - } - if (px->in_flag == 2) - { - fprintf(stderr, "redir <<\n"); - write_here_doc_tmp(px); - fd_in = open(".tmp", O_RDONLY); - if (dup2(fd_in, STDIN_FILENO) < 0) - printf("error dup"); //ft_error_free_exit("dup error 1", NULL, px); - unlink(".tmp"); - close(fd_in); - } - fprintf(stderr, "he pasado por redirect input\n"); -} - -/* - dup2 command output: - if n = 1: > (output file trunc?) - if n = 2: >> (output file append) -*/ -void ft_output_redirect(t_px *px) -{ - int fd_out; - - if (px->out_flag == 1) - { - printf("redir >\n"); - fd_out = open(px->outfile, O_CREAT | O_WRONLY | O_TRUNC, 0644); - if (dup2(fd_out, STDOUT_FILENO) < 0) - printf("error dup"); //ft_error_free_exit("dup error 1", NULL, px); - close(fd_out); - } - if (px->out_flag == 2) - { - printf("redir >>\n"); - fd_out = open(px->outfile, O_CREAT | O_WRONLY | O_APPEND, 0644); - if (dup2(fd_out, STDOUT_FILENO) < 0) - printf("error dup"); //ft_error_free_exit("dup error 1", NULL, px); - close(fd_out); - } - fprintf(stderr, "he pasado por redirect output\n"); -} - -/* - n = command index -*/ -void ft_child(t_px *px, int n) -{ - - fprintf(stderr, "estoy en childs\n"); - if (px->info->cmd_amount > 1) - ft_fd_pipes(px, n); - if (px->in_flag > 0) - ft_input_redirect(px); // open input file, dup - (<, <<) - if (px->out_flag > 0) - ft_output_redirect(px); // open output file, dup - (>, >>) - ft_fd_close(px, px->info->cmd_amount - 1); - execve(px->path, px->full_cmd, NULL); -} - - -void pipex(t_px *px) -{ - pid_t pid; - int i; - - ft_alloc_fd(px); - i = 0; - while (i < px->info->cmd_amount) - { - pid = fork(); - if (pid == 0) - ft_child(&px[i], i); - ft_fd_close(px, i); - waitpid(pid, NULL, 0); - i++; - } - if (px->info->cmd_amount > 1) - ft_free_fd(px); -} - -int check_slash(char *str) -{ - int i; - int slash; - - slash = 0; - i = 0; - while (str[i]) //buscar si hay '/' en el str que llega - { - if (str[i] == '/') - slash++; - i++; - } - return (slash); -} -char **get_path(char **env) -{ - int i; - - i = 0; - while (env[i]) // - { - if (ft_strnstr(env[i], "PATH=", 5)) - return(ft_split(env[i] + 5, ':')); - i++; - } - return (NULL); -} - -/* - Checks if cmd or /path/cmd exists. - Returns (/path/cmd) allocated if so - Returns (NULL) otherwise -*/ -char *get_cmd_or_cmdpath(char **env, char *str) -{ - int i; - char **env_path; - char *aux; - char *path_and_cmd; - - env_path = NULL; - i = 0; - if (check_slash(str) > 0 && !access(str, F_OK)) // si hay '/' probar si es ruta + comando valido - return (ft_strdup(str)); //BE CAREFUL check if str comes allocated!!!!!! - else if (check_slash(str) == 0) // si no hay '/' comprobar si es un comando valido: - { // buscar path y splitearlo - env_path = get_path(env); - i = 0; - while (env_path[i]) //ir probando paths y ver si ruta + (join) comando existe - { - aux = ft_strjoin(env_path[i++], "/"); - path_and_cmd = ft_strjoin(aux, str); - free(aux); - if (access(path_and_cmd, F_OK) == 0) - return (ft_free_split(env_path), path_and_cmd); - free(path_and_cmd); - } - ft_free_split(env_path); - } - return (NULL); -} diff --git a/oldies/libft.a b/oldies/libft.a deleted file mode 100644 index 752edad..0000000 Binary files a/oldies/libft.a and /dev/null differ diff --git a/oldies/manolita.txt b/oldies/manolita.txt deleted file mode 100644 index e69de29..0000000 diff --git a/oldies/manolite.txt b/oldies/manolite.txt deleted file mode 100644 index e69de29..0000000 diff --git a/oldies/manolito.txt b/oldies/manolito.txt deleted file mode 100644 index e69de29..0000000 diff --git a/oldies/pruebas.c b/oldies/pruebas.c deleted file mode 100644 index 86ab898..0000000 --- a/oldies/pruebas.c +++ /dev/null @@ -1,69 +0,0 @@ -/*#include -#include -#include"../src/parse.h" - - -int main() -{ - DIR *dir; - struct dirent *entry; - // Abre el directorio actual (".") - dir = opendir("."); - memset(&entry, 0, sizeof(struct dirent)); - while (entry != NULL) - { - entry = readdir(dir); - printf("Nombre de archivo o directorio: %s\n", entry->d_name); - } - closedir(dir); - - - return 0; -} -*/ - -#include -#include -#include -#include - -int coincideConPatron(const char *nombre, const char *patron) { - // Comprueba si el nombre del archivo coincide con el patrón - int longitudNombre = strlen(nombre); - int longitudPatron = strlen(patron); - - if (longitudPatron == 0) { - return 1; // Si el patrón está vacío, cualquier nombre coincide - } - - if (longitudNombre < longitudPatron) { - return 0; // El nombre es más corto que el patrón, no coincide - } - - if (patron[longitudPatron - 1] == '*') { - return strncmp(nombre, patron, longitudPatron - 1) == 0; // Comodín al final - } - - return strcmp(nombre, patron) == 0; // Sin comodín -} - -int main() { - DIR *dir; - struct dirent *entry; - const char *patron = "*.c"; // Patrón para archivos "prueba*" - - dir = opendir("."); - - if (dir) { - while ((entry = readdir(dir)) != NULL) { - if (entry->d_type == DT_REG) { // Comprueba si es un archivo regular - if (coincideConPatron(entry->d_name, patron)) { - printf("Nombre de archivo: %s\n", entry->d_name); - } - } - } - closedir(dir); - } - - return 0; -} diff --git a/oldies/testdir.c b/oldies/testdir.c deleted file mode 100644 index 29582e9..0000000 --- a/oldies/testdir.c +++ /dev/null @@ -1,25 +0,0 @@ -#include -#include -#include"../src/parse.h" - - -int main() -{ - DIR *dir; - struct dirent *entry; - // Abre el directorio actual (".") - dir = opendir("."); - - entry = readdir(dir); - while (entry != NULL) - { - printf("Nombre de archivo o directorio: %s\n", entry->d_name); - entry = readdir(dir); - } - - closedir(dir); - - - - return 0; -} diff --git a/oldies/wc_it.c b/oldies/wc_it.c deleted file mode 100644 index f079f40..0000000 --- a/oldies/wc_it.c +++ /dev/null @@ -1,63 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* wc_it.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: imontero +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2023/10/30 09:03:47 by imontero #+# #+# */ -/* Updated: 2023/10/30 09:12:28 by imontero ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include - -/* -saving backup positions and restoring them when needed. -If a mismatch occurs without available wildcards, -it returns 0 for no match. After the loop, -it skips any remaining asterisk wildcards in the pattern. -If the end of the pattern is reached, it's considered a match. -*/ -int wc_find_match(char *pattern, char *str) -{ - int str_idx = 0; - int pat_idx = 0; - int str_b = -1; - int pat_b = -1; - - while (str[str_idx]) - { - if (pattern[pat_idx] == '*') - { - pat_b = ++pat_idx; - str_b = str_idx; - } - else if (pattern[pat_idx] == str[str_idx]) - { - pat_idx++; - str_idx++; - } - else if (pat_b >= 0) - { - pat_idx = pat_b; - str_idx = ++str_b; - } - else - return 0; - } - while (pattern[pat_idx] == '*') - pat_idx++; - return (pattern[pat_idx] == '\0'); -} - -int main(void) -{ - char *pattern = "mi*ni*"; - char *str = "minishell.c"; - if (wc_find_match(pattern, str)) - printf("Matched: %s\n", str); - else - printf("No match found.\n"); - return (0); -} diff --git a/oldies/wc_rec.c b/oldies/wc_rec.c deleted file mode 100644 index eb6e75b..0000000 --- a/oldies/wc_rec.c +++ /dev/null @@ -1,50 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* wc_rec.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: imontero +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2023/10/30 09:13:29 by imontero #+# #+# */ -/* Updated: 2023/10/30 17:02:18 by imontero ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include - -int find_wild_match(char *pattern, char *str) -{ - while (*pattern) - { - if (*pattern == '*') - { - while (*pattern == '*') - pattern++; - if (*pattern == '\0') - return (1); - while (*str) - { - if (*str == *pattern && find_wild_match(pattern, str)) - return (1); - str++; - } - return 0; - } - if (*str == '\0' || (*pattern != *str)) - return (0); - pattern++; - str++; - } - return (*str == '\0'); -} - -int main() { - const char *pattern = "*.c"; - const char *str = "minishell.c"; - if (find_wild_match(pattern, str)) { - printf("Matched: %s\n", str); - } else { - printf("No match found.\n"); - } - return 0; -} diff --git a/oldies/wildcard_aux.c b/oldies/wildcard_aux.c deleted file mode 100644 index 197a96c..0000000 --- a/oldies/wildcard_aux.c +++ /dev/null @@ -1,77 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* wildcard_aux.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: imontero +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2023/10/30 11:02:32 by imontero #+# #+# */ -/* Updated: 2023/10/31 08:48:54 by imontero ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include"../src/parse.h" - -int ft_matlen(char **mat) -{ - int len; - - len = 0; - while (mat[len]) - len++; - return (len); -} - -int count_dir(void) -{ - DIR *dir; - struct dirent *entry; - int count; - - count = 0; - dir = opendir("."); - entry = readdir(dir); - while (entry != NULL) - { - entry = readdir(dir); - count++; - } - closedir(dir); - return (count); -} - -char **create_exp_cmdargs(char **cmdargs) -{ - char **exp_cmdargs; - - exp_cmdargs = malloc(sizeof(char *) * (ft_matlen(cmdargs) * count_dir())); - ft_bzero(exp_cmdargs, sizeof(char *) * (ft_matlen(cmdargs) * count_dir())); - exp_cmdargs[0] = ft_strdup(cmdargs[0]); - return (exp_cmdargs); -} - -int find_wild_match(char *pattern, char *str) -{ - while (*pattern) - { - if (*pattern == '*') - { - while (*pattern == '*') - pattern++; - if (*pattern == '\0') - return (1); - while (*str) - { - if (*str == *pattern && find_wild_match(pattern, str)) - return (1); - str++; - } - return (0); - } - if (*str == '\0' || (*pattern != *str)) - return (0); - pattern++; - str++; - } - return (*str == '\0'); -} diff --git a/out b/out deleted file mode 100644 index e69de29..0000000 diff --git a/precedenceclimbing/a.out b/precedenceclimbing/a.out new file mode 100755 index 0000000..f6d0af1 Binary files /dev/null and b/precedenceclimbing/a.out differ diff --git a/precedenceclimbing/main.c b/precedenceclimbing/main.c new file mode 100644 index 0000000..3101172 --- /dev/null +++ b/precedenceclimbing/main.c @@ -0,0 +1,8 @@ +#include + +int main(void) +{ + int i = 5; + + printf("%i\n", i / 2); +} \ No newline at end of file diff --git a/precedenceclimbing/prcedence.py b/precedenceclimbing/prcedence.py new file mode 100644 index 0000000..a61971e --- /dev/null +++ b/precedenceclimbing/prcedence.py @@ -0,0 +1,142 @@ +from collections import namedtuple +import re + + +Tok = namedtuple('Tok', 'name value') + + +class Tokenizer(object): + """ Simple tokenizer object. The cur_token attribute holds the current + token (Tok). Call get_next_token() to advance to the + next token. cur_token is None before the first token is + taken and after the source ends. + """ + TOKPATTERN = re.compile("\s*(?:(\d+)|(.))") + + def __init__(self, source): + self._tokgen = self._gen_tokens(source) + self.cur_token = None + + def get_next_token(self): + """ Advance to the next token, and return it. + """ + try: + self.cur_token = next(self._tokgen) + except StopIteration: + self.cur_token = None + return self.cur_token + + def _gen_tokens(self, source): + for number, operator in self.TOKPATTERN.findall(source): + if number: + yield Tok('NUMBER', number) + elif operator == '(': + yield Tok('LEFTPAREN', '(') + elif operator == ')': + yield Tok('RIGHTPAREN', ')') + else: + yield Tok('BINOP', operator) + + def __repr__(self): + return 'Tokenizer(cur_token=%s)' % str(self.cur_token) + + +# For each operator, a (precedence, associativity) pair. +OpInfo = namedtuple('OpInfo', 'prec assoc') + +OPINFO_MAP = { + '+': OpInfo(1, 'LEFT'), + '-': OpInfo(1, 'LEFT'), + '*': OpInfo(2, 'LEFT'), + '/': OpInfo(2, 'LEFT'), + '^': OpInfo(3, 'RIGHT'), +} + + +def parse_error(msg): + raise RuntimeError(msg) + +def compute_atom(tokenizer): + tok = tokenizer.cur_token + if tok.name == 'LEFTPAREN': + tokenizer.get_next_token() + val = compute_expr(tokenizer, 1) + if tokenizer.cur_token.name != 'RIGHTPAREN': + parse_error('unmatched "("') + tokenizer.get_next_token() + return val + elif tok is None: + parse_error('source ended unexpectedly') + elif tok.name == 'BINOP': + parse_error('expected an atom, not an operator "%s"' % tok.value) + else: + assert tok.name == 'NUMBER' + tokenizer.get_next_token() + return int(tok.value) + + +def compute_expr(tokenizer, min_prec): + atom_lhs = compute_atom(tokenizer) + + while True: + cur = tokenizer.cur_token + if (cur is None or cur.name != 'BINOP' + or OPINFO_MAP[cur.value].prec < min_prec): + break + + # Inside this loop the current token is a binary operator + assert cur.name == 'BINOP' + + # Get the operator's precedence and associativity, and compute a + # minimal precedence for the recursive call + op = cur.value + prec, assoc = OPINFO_MAP[op] + next_min_prec = prec + 1 if assoc == 'LEFT' else prec + + # Consume the current token and prepare the next one for the + # recursive call + tokenizer.get_next_token() + atom_rhs = compute_expr(tokenizer, next_min_prec) + + # Update lhs with the new value + atom_lhs = compute_op(op, atom_lhs, atom_rhs) + + return atom_lhs + + +def compute_op(op, lhs, rhs): + lhs = int(lhs); rhs = int(rhs) + if op == '+': return lhs + rhs + elif op == '-': return lhs - rhs + elif op == '*': return lhs * rhs + elif op == '/': return lhs / rhs + elif op == '^': return lhs ** rhs + else: + parse_error('unknown operator "%s"' % op) + + +def test(): + def compute(s): + t = Tokenizer(s) + t.get_next_token() + return compute_expr(t, 1) + + assert compute('1 + 2 * 3') == 7 + assert compute('7 - 9 * (2 - 3)') == 16 + assert compute('2 * 3 * 4') == 24 + assert compute('2 ^ 3 ^ 4') == 2 ** (3 ** 4) + assert compute('(2 ^ 3) ^ 4') == 4096 + assert compute('5') == 5 + assert compute('4 + 2') == 6 + assert compute('9 - 8 - 7') == -6 + assert compute('9 - (8 - 7)') == 8 + assert compute('(9 - 8) - 7') == -6 + assert compute('2 + 3 ^ 2 * 3 + 4') == 33 + + +if __name__ == '__main__': + test() + + t = Tokenizer('2 + 3^2*3 + 4') + t.get_next_token() + print(compute_expr(t, min_prec=1)) \ No newline at end of file diff --git a/precedenceclimbing/precedence.c b/precedenceclimbing/precedence.c new file mode 100644 index 0000000..0f19561 --- /dev/null +++ b/precedenceclimbing/precedence.c @@ -0,0 +1,132 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* precedence.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: codespace +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/11/08 11:18:46 by codespace #+# #+# */ +/* Updated: 2023/11/08 14:50:24 by codespace ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include"../inc/parse_bonus.h" + +int compute_expr(char **nodes, int *i, int min_prec, int nnodes_len); + +int ft_atoi(const char *str) +{ + unsigned int i; + int sign; + int nbr; + + i = 0; + sign = 1; + nbr = 0; + while ((str[i] >= 9 && str[i] <= 13) || str[i] == 32) + i++; + if (str[i] == '-') + { + sign *= -1; + i++; + } + else if (str[i] == '+') + i++; + while (str[i] >= '0' && str[i] <= '9' && str[i]) + { + nbr = nbr * 10 + str[i] - '0'; + i++; + } + return (nbr * sign); +} + +int ft_get_prec(char *c) +{ + if (*c == '+' || *c == '-') + return (1); + else if (*c == '*' || *c == '/') + return (2); + else if (*c == '(') + return (8); + else if (*c == ')') + return (9); + return (0); +} + +int compute_atom(char **nodes, int *i, int nodes_len) +{ + int res; + + if (ft_get_prec(nodes[*i]) == 8) + { + (*i)++; + res = compute_expr(nodes, i, 1, nodes_len); + if (ft_get_prec(nodes[*i]) != 9) + return (printf("unmatched '('"), 9999); + (*i)++; + return (res); + } + else if (ft_get_prec(nodes[*i]) != 0) + return (printf("Expecting a command not an operator"), 9999); + else + { + res = ft_atoi(nodes[(*i)]); + (*i)++; + return (res); + } +} + +int compute_op(char *op, int lhs, int rhs) +{ + if ((*op) == '+') + return (lhs + rhs); + else if ((*op) == '-') + return (lhs - rhs); + else if ((*op) == '*') + return (lhs * rhs); + else if ((*op) == '/') + return (lhs / rhs); + else + return(printf("Unknown operator"), 9999); +} + +int compute_expr(char **nodes, int *i, int min_prec, int nodes_len) +{ + int prec; + int next_min_prec; + int atom_rhs; + int atom_lhs; + char *op; + + atom_lhs = compute_atom(nodes, i, nodes_len); + if (atom_lhs == 9999) + return (9999); + while (*i < nodes_len) + { + op = nodes[(*i)]; + prec = ft_get_prec(nodes[(*i)]); + if (prec < min_prec || prec > 8) + break ; + next_min_prec = prec + 1; + (*i)++; + atom_rhs = compute_expr(nodes, i, next_min_prec, nodes_len); + atom_lhs = compute_op(op, atom_lhs, atom_rhs); + if (atom_lhs == 9999) + return (9999); + } + return (atom_lhs); +} + +int main(void) +{ + char *expr = "( 2 + 2 ) * 3"; + char **split; + int i = 0; + + split = ft_split(expr, ' '); + //split[0] = "56"; + //split[1] = "/"; + //split[2] = "2"; + printf("Result: %i\n", compute_expr(split, &i, 1, 7)); + return (0); +} \ No newline at end of file diff --git a/src/builtins/bt_cd.c b/src/builtins/bt_cd.c index 5007d31..34ce407 100644 --- a/src/builtins/bt_cd.c +++ b/src/builtins/bt_cd.c @@ -3,10 +3,10 @@ /* ::: :::::::: */ /* bt_cd.c :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: imontero +#+ +:+ +#+ */ +/* By: codespace +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/10/23 10:32:00 by imontero #+# #+# */ -/* Updated: 2023/10/31 11:16:23 by imontero ### ########.fr */ +/* Updated: 2023/11/13 09:51:11 by codespace ### ########.fr */ /* */ /* ************************************************************************** */ @@ -56,10 +56,8 @@ void ft_cd_oldpwd(t_px *px, char ***envcpy) char **ft_cd(t_px *px) { - //char *path; char **envcpy; - //path = NULL; envcpy = px->info->envcp; if (px->full_cmd[1] == NULL || ft_strcmp(px->full_cmd[1], "--") == 0) ft_cd_home(px, &envcpy); diff --git a/src/envutils/envcp.c b/src/envutils/envcp.c index 19d42ec..8c69f94 100644 --- a/src/envutils/envcp.c +++ b/src/envutils/envcp.c @@ -3,10 +3,10 @@ /* ::: :::::::: */ /* envcp.c :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: imontero +#+ +:+ +#+ */ +/* By: codespace +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/10/17 10:08:01 by imontero #+# #+# */ -/* Updated: 2023/10/31 11:16:23 by imontero ### ########.fr */ +/* Updated: 2023/11/13 09:51:57 by codespace ### ########.fr */ /* */ /* ************************************************************************** */ diff --git a/src/main.c b/src/main.c index f3972ae..fb8e716 100644 --- a/src/main.c +++ b/src/main.c @@ -3,18 +3,16 @@ /* ::: :::::::: */ /* main.c :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: jzubizar +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/10/14 18:50:48 by josu #+# #+# */ -/* Updated: 2023/11/02 11:09:53 by jzubizar ### ########.fr */ +/* Updated: 2023/11/13 11:21:35 by codespace ### ########.fr */ /* */ /* ************************************************************************** */ -#include"../inc/parse.h" -//#include +#include "../inc/parse.h" #include - //Function to handle SIGINT signal received void ft_handle_client(int sig) { @@ -40,6 +38,14 @@ void ft_2nd_handler(int sig) } } +//Function to free all the content in INFO +void ft_free_info(t_info *info) +{ + if (info->envcp) + ft_free_split(info->envcp); + free (info); +} + int main(int argc, char **argv, char **env) { t_info *info; @@ -61,6 +67,6 @@ int main(int argc, char **argv, char **env) if (!info->homepath) return (printf("Invalid Home\n"), -1); terminal(info); - free(info); + ft_free_info(info); return (g_stat); } diff --git a/src/parser/executor.c b/src/parser/executor.c index d3c5ff5..862a01a 100644 --- a/src/parser/executor.c +++ b/src/parser/executor.c @@ -3,10 +3,10 @@ /* ::: :::::::: */ /* executor.c :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: jzubizar +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/10/25 18:47:42 by imontero #+# #+# */ -/* Updated: 2023/11/02 12:14:43 by jzubizar ### ########.fr */ +/* Updated: 2023/11/09 11:55:51 by codespace ### ########.fr */ /* */ /* ************************************************************************** */ diff --git a/src/parser/executor_bonus.c b/src/parser/executor_bonus.c new file mode 100644 index 0000000..03ee8a1 --- /dev/null +++ b/src/parser/executor_bonus.c @@ -0,0 +1,142 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* executor_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: codespace +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/10/25 18:47:42 by imontero #+# #+# */ +/* Updated: 2023/11/14 10:23:22 by codespace ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../../inc/parse_bonus.h" + +/* + if there is more than 1 command, make dups. + cases: + - first cmd: dup2 stdout (if there is no >, >>) + - middle cmd: dup2 stdin & stdout (if there is no >, >> or <, <<) + - last cmd: dup2 stdin (if there is no <, <<) +*/ +void ft_fd_pipes(t_px *px, int n) +{ + n = (n / 2) + (n % 2); + if (n == 0 && px->out_flag == 0) + { + if (dup2(px->info->fd[n][1], STDOUT_FILENO) < 0) + ft_error(DUPERR, NULL, 5); + } + else if (n == px->cmd_num - 1 && px->in_flag == 0) + { + if (dup2(px->info->fd[n - 1][0], STDIN_FILENO) < 0) + ft_error(DUPERR, NULL, 5); + } + else if (n > 0 && n < px->cmd_num - 1) + { + if (px->out_flag == 0) + { + if (dup2(px->info->fd[n][1], STDOUT_FILENO) < 0) + ft_error(DUPERR, NULL, 5); + } + if (px->in_flag == 0) + { + if (dup2(px->info->fd[n - 1][0], STDIN_FILENO) < 0) + ft_error(DUPERR, NULL, 5); + } + } +} + +/* + dup2 command input: + if n = 1: < (infile) + if n = 2: << (here_doc) +*/ +void ft_input_redirect(t_px *px) +{ + int fd_in; + + if (px->in_flag == 1) + { + fd_in = open(px->infile, O_RDONLY); + if (dup2(fd_in, STDIN_FILENO) < 0) + ft_error(DUPERR, NULL, 5); + close(fd_in); + } + if (px->in_flag == 2) + { + write_here_doc_tmp(px); + fd_in = open(".tmp", O_RDONLY); + if (dup2(fd_in, STDIN_FILENO) < 0) + ft_error(DUPERR, NULL, 5); + unlink(".tmp"); + close(fd_in); + } +} + +/* + dup2 command output: + if n = 1: > (output file trunc?) + if n = 2: >> (output file append) +*/ +void ft_output_redirect(t_px *px) +{ + int fd_out; + + if (px->out_flag == 1) + { + fd_out = open(px->outfile, O_CREAT | O_WRONLY | O_TRUNC, 0644); + if (dup2(fd_out, STDOUT_FILENO) < 0) + ft_error(DUPERR, NULL, 5); + close(fd_out); + } + if (px->out_flag == 2) + { + fd_out = open(px->outfile, O_CREAT | O_WRONLY | O_APPEND, 0644); + if (dup2(fd_out, STDOUT_FILENO) < 0) + ft_error(DUPERR, NULL, 5); + close(fd_out); + } +} + +int pipex_p(t_px *px) +{ + pid_t pid; + int i; + + i = 0; + while (i < px->cmd_real_num) + { + if (px[i].in_flag == 2) + { + sa.sa_handler = SIG_IGN; + sigaction(SIGQUIT, &sa, NULL); + } + if (px[i].type != BIp && px[i].type != T_PIPE) + { + pid = fork(); + if (pid < 0) + return (ft_error(FORKERR, NULL, 4), 1); + pipex_p_aux(px, i, pid); + } + else if (px[i].type != T_PIPE) + ft_fd_close(px, i); + i++; + } + return (0); +} + +void pipex(t_px *px) +{ + struct sigaction sa; + + sa.sa_handler = &ft_2nd_handler; + sigaction(SIGINT, &sa, NULL); + sigaction(SIGQUIT, &sa, NULL); + ft_alloc_fd(px); + if (!px->info->fd) + return ; + if (pipex_p(px)) + return ; + ft_free_fd(px); +} diff --git a/src/parser/getpaths_bonus.c b/src/parser/getpaths_bonus.c new file mode 100644 index 0000000..106b53b --- /dev/null +++ b/src/parser/getpaths_bonus.c @@ -0,0 +1,108 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* getpaths_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: codespace +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/10/25 18:47:42 by imontero #+# #+# */ +/* Updated: 2023/11/14 10:28:34 by codespace ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../../inc/parse_bonus.h" + +int check_slash(char *str) +{ + int i; + int slash; + + slash = 0; + i = 0; + while (str[i]) + { + if (str[i] == '/') + slash++; + i++; + } + return (slash); +} + +char **get_path(char **env) +{ + int i; + + i = 0; + while (env[i]) + { + if (ft_strnstr(env[i], "PATH=", 5)) + return (ft_split(env[i] + 5, ':')); + i++; + } + return (NULL); +} + +/* + Checks if cmd or /path/cmd exists. + Returns (/path/cmd) allocated if so + Returns (NULL) otherwise +*/ +char *get_cmd_or_cmdpath(char **env, char *str) +{ + int i; + char **env_path; + char *aux; + char *path_and_cmd; + + env_path = NULL; + if (check_slash(str) > 0 && !access(str, F_OK)) + return (ft_strdup(str)); + else if (check_slash(str) == 0) + { + env_path = get_path(env); + i = 0; + while (env_path[i]) + { + aux = ft_strjoin(env_path[i++], "/"); + path_and_cmd = ft_strjoin(aux, str); + free(aux); + if (access(path_and_cmd, F_OK) == 0) + return (ft_free_split(env_path), path_and_cmd); + free(path_and_cmd); + } + if (env_path) + ft_free_split(env_path); + } + return (NULL); +} + +void ft_fd_close(t_px *px, int qj) +{ + int i; + int j; + + i = 0; + j = (qj / 2) + (qj % 2); + while (i < j) + { + close(px->info->fd[i][0]); + close(px->info->fd[i][1]); + i++; + } +} + +void ft_alloc_fd(t_px *px) +{ + int i; + + i = 0; + px->info->fd = malloc(sizeof(int *) * (px->cmd_num - 1)); + if (!px->info->fd) + return ; + while (i < px->cmd_num - 1) + { + px->info->fd[i] = malloc(sizeof(int) * 2); + pipe(px->info->fd[i]); + i++; + } +} diff --git a/src/parser/heredoc_bonus.c b/src/parser/heredoc_bonus.c new file mode 100644 index 0000000..4040d7b --- /dev/null +++ b/src/parser/heredoc_bonus.c @@ -0,0 +1,114 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* heredoc_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: codespace +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/10/25 18:52:08 by imontero #+# #+# */ +/* Updated: 2023/11/09 13:09:47 by codespace ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../../inc/parse_bonus.h" + +void ft_getline_aux(char c, char **str) +{ + char *aux; + char *tmp; + + aux = *str; + tmp = malloc(2 * sizeof(char)); + tmp[0] = c; + tmp[1] = 0; + *str = ft_strjoin(*str, tmp); + free(tmp); + free(aux); +} + +char *ft_getline(int fd) +{ + char c; + char *str; + int re; + + str = malloc(1 * sizeof(char)); + str[0] = 0; + re = read(fd, &c, 1); + while (re >= 0) + { + if (!str[0] && re == 0) + return (NULL); + ft_getline_aux(c, &str); + if (c == '\n') + break ; + c = 0; + re = read(fd, &c, 1); + } + return (str); +} + +void write_here_doc_tmp(t_px *px) +{ + char *line; + char *limit_n; + int fd; + + fd = open(".tmp", O_CREAT | O_WRONLY | O_TRUNC, 0644); + while (1) + { + line = ft_getline(0); + if (line == NULL) + break ; + limit_n = ft_strjoin(px->limit, "\n"); + if (ft_strcmp(limit_n, line) == 0) + { + free(limit_n); + break ; + } + free(limit_n); + ft_putstr_fd(line, fd); + free(line); + } + free(line); + close(fd); +} + +void ft_free_fd(t_px *px) +{ + int i; + + i = 0; + while (i < px->cmd_num - 1) + { + free(px->info->fd[i]); + i++; + } + free(px->info->fd); +} + +/* + n = command index +*/ +void ft_child(t_px *px, int n) +{ + struct sigaction sa; + + sa.sa_handler = SIG_DFL; + sigaction(SIGINT, &sa, NULL); + if (px->cmd_num > 1) + ft_fd_pipes(px, n); + if (px->in_flag > 0) + ft_input_redirect(px); + if (px->out_flag > 0) + ft_output_redirect(px); + ft_fd_close(px, px->cmd_real_num - 1); + sa.sa_handler = SIG_DFL; + sigaction(SIGQUIT, &sa, NULL); + if (px->type == BIc) + { + ft_execbi_child(px); + exit(1); + } + execve(px->path, px->full_cmd, NULL); +} diff --git a/src/parser/parser.c b/src/parser/parser.c index 40051de..ffde58f 100644 --- a/src/parser/parser.c +++ b/src/parser/parser.c @@ -3,10 +3,10 @@ /* ::: :::::::: */ /* parser.c :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: imontero +#+ +:+ +#+ */ +/* By: codespace +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/10/10 17:59:57 by josu #+# #+# */ -/* Updated: 2023/10/31 12:33:57 by imontero ### ########.fr */ +/* Updated: 2023/11/13 10:17:34 by codespace ### ########.fr */ /* */ /* ************************************************************************** */ @@ -37,9 +37,7 @@ char **ft_fill_full_cmd(t_px *node, int num_arg, char **str) char **ft_parse_loop(t_px *node, char **str, char **env) { int num_arg; - //int i; - //i = 0; str = ft_inout_file(node, str); while (*str && ft_strncmp("|", *str, 2)) { diff --git a/src/parser/parser_bonus.c b/src/parser/parser_bonus.c new file mode 100644 index 0000000..e0475ed --- /dev/null +++ b/src/parser/parser_bonus.c @@ -0,0 +1,87 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* parser_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: codespace +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/10/10 17:59:57 by josu #+# #+# */ +/* Updated: 2023/11/14 10:33:50 by codespace ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../../inc/parse_bonus.h" + +//Function to free the nodes array +void ft_free_nodes(t_px *nodes) +{ + int len; + int i; + + len = (*nodes).info->cmd_amount; + i = 0; + while (i < len) + { + if (nodes[i].full_cmd) + { + ft_free_split(nodes[i].full_cmd); + } + if (nodes[i].path) + free(nodes[i].path); + if (nodes[i].infile) + free(nodes[i].infile); + if (nodes[i].outfile) + free(nodes[i].outfile); + if (nodes[i].limit) + free(nodes[i].limit); + i++; + } + free(nodes); +} + +//Returns the str info into an array of t_px +//Mallocs space for array of t_px and for the general info +//It does not free the str +t_px *ft_parse(char **str, t_info *info) +{ + t_px *nodes; + int i; + + i = 0; + info->cmd_amount = ft_node_quant(str); + info->fd = NULL; + nodes = ft_init_nodes(info); + if (!nodes) + return (ft_free_info(info), NULL); + while (i < info->cmd_amount) + { + str = ft_parse_loop(&nodes[i], str, info->envcp); + ft_wildcard(&nodes[i]); + i++; + } + ft_num_node_cmd(nodes); + if (ft_check_nodes(nodes)) + return (ft_free_nodes(nodes), NULL); + return (nodes); +} + +void ft_stat_signaled(void) +{ + if (WIFSIGNALED(g_stat)) + g_stat = 130; + else + g_stat = WEXITSTATUS(g_stat); +} + +void pipex_p_aux(t_px *px, int i, pid_t pid) +{ + struct sigaction sa; + + if (pid == 0) + ft_child(&px[i], i); + ft_fd_close(px, i); + waitpid(pid, &g_stat, 0); + ft_stat_signaled(); + sa.sa_handler = &ft_2nd_handler; + sigaction(SIGQUIT, &sa, NULL); +} diff --git a/src/parser/parser_util.c b/src/parser/parser_util.c index 640ff5a..ccb2b79 100644 --- a/src/parser/parser_util.c +++ b/src/parser/parser_util.c @@ -3,10 +3,10 @@ /* ::: :::::::: */ /* parser_util.c :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: imontero +#+ +:+ +#+ */ +/* By: codespace +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/10/25 19:17:01 by jzubizar #+# #+# */ -/* Updated: 2023/10/31 11:16:41 by imontero ### ########.fr */ +/* Updated: 2023/11/13 10:02:10 by codespace ### ########.fr */ /* */ /* ************************************************************************** */ @@ -48,7 +48,8 @@ int ft_num_args(char **str) i = 0; while (*str && ft_strncmp(*str, "|", 2) && ft_strncmp(*str, "&&", 3) - && ft_strncmp(*str, "||", 3)) + && ft_strncmp(*str, "||", 3) && ft_strncmp(*str, ")", 2) + && ft_strncmp(*str, "(", 2)) { if (!ft_strncmp(*str, ">>", 3) || !ft_strncmp(*str, ">", 2) || !ft_strncmp(*str, "<<", 3) || !ft_strncmp(*str, "<", 3)) diff --git a/src/parser/parser_util2_bonus.c b/src/parser/parser_util2_bonus.c new file mode 100644 index 0000000..2416108 --- /dev/null +++ b/src/parser/parser_util2_bonus.c @@ -0,0 +1,157 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* parser_util2_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: codespace +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/10/10 17:59:57 by josu #+# #+# */ +/* Updated: 2023/11/14 10:44:41 by codespace ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../../inc/parse_bonus.h" + +//Function to fill the complete args array +char **ft_fill_full_cmd(t_px *node, int num_arg, char **str) +{ + int i; + + i = 0; + node->full_cmd = malloc(sizeof(char *) * (num_arg + 1)); + if (node->full_cmd) + node->full_cmd[i++] = ft_strdup(node->path); + str++; + while (i < num_arg && node->full_cmd) + { + str = ft_inout_file(node, str); + node->full_cmd[i] = ft_strdup(*str); + i++; + str++; + } + if (node->full_cmd) + node->full_cmd[i] = NULL; + return (str); +} + +void ft_num_node_cmd(t_px *nodes) +{ + int i; + int i_init; + int cnt; + + i = 0; + while (i < nodes->info->cmd_amount) + { + cnt = 0; + if (nodes[i].type == CMD || nodes[i].type == BIc) + { + i_init = i; + while (i < nodes->info->cmd_amount && (nodes[i].type == CMD + || nodes[i].type == BIc || nodes[i].type == T_PIPE)) + if (nodes[i++].type != T_PIPE) + cnt++; + i = i_init; + while (i < nodes->info->cmd_amount && (nodes[i].type == CMD + || nodes[i].type == BIc || nodes[i].type == T_PIPE)) + { + nodes[i].cmd_real_num = 2 * cnt - 1; + nodes[i++].cmd_num = cnt; + } + } + i++; + } +} + +//Function to process and fill info of a single node +char **ft_parse_loop(t_px *node, char **str, char **env) +{ + int num_arg; + + str = ft_inout_file(node, str); + if (!ft_is_cm(*str, node)) + node->path = get_cmd_or_cmdpath(env, *str); + else if (node->type == BIp || node->type == BIc) + node->path = ft_strdup(*str); + else + return (++str); + num_arg = ft_num_args(str); + str = ft_fill_full_cmd(node, num_arg, str); + if (*str) + str = ft_inout_file(node, str); + return (str); +} + +//Function to init in zeros the array of t_px +t_px *ft_init_nodes(t_info *info) +{ + t_px *nodes; + int i; + + i = 0; + nodes = malloc(sizeof(t_px) * info->cmd_amount); + if (!nodes) + return (ft_error(MEM, NULL, 2)); + while (i < info->cmd_amount) + { + nodes[i].full_cmd = NULL; + nodes[i].path = NULL; + nodes[i].infile = NULL; + nodes[i].outfile = NULL; + nodes[i].limit = NULL; + nodes[i].in_flag = 0; + nodes[i].out_flag = 0; + nodes[i].type = 0; + nodes[i].info = info; + nodes[i].cmd_num = 0; + i++; + } + return (nodes); +} + +//Check inapropriate node, returns 0 if OK +int ft_err_node(t_px node) +{ + if (!node.path && (node.type == CMD || node.type == BIc + || node.type == BIp)) + return (ft_error(NCMD, NULL, 127), node.full_cmd[0] = \ + ft_strdup("(null)"), 2); + if (!node.full_cmd && (node.type == CMD || node.type == BIc + || node.type == BIp)) + return (1); + if (node.out_flag && !node.outfile) + return (ft_error(SYNERR, NULL, 20), 4); + else if (node.out_flag && access(node.outfile, F_OK) < 0) + return (0); + else if (node.out_flag && access(node.outfile, W_OK) < 0) + return (ft_error(NPERM, node.outfile, 126), 5); + if (node.in_flag == 1 && !node.infile) + return (ft_error(SYNERR, NULL, 20), 4); + else if (node.in_flag == 1 && access(node.infile, F_OK) < 0) + return (ft_error(NDIR, node.infile, 30), 6); + else if (node.in_flag == 1 && access(node.infile, R_OK) < 0) + return (ft_error(NPERM, node.infile, 126), 5); + if (node.in_flag == 2 && !node.limit) + return (ft_error(SYNERR, NULL, 20), 4); + if (node.in_flag == 2 && (access(".tmp", F_OK) == 0 + && access(".tmp", W_OK) < 0)) + return (ft_error(NPERM, ".temp", 126), 5); + return (0); +} + +//Function to check if every malloc filling the nodes where correctly done +int ft_check_nodes(t_px *nodes) +{ + int len; + int i; + + len = (*nodes).info->cmd_amount; + i = 0; + while (i < len) + { + if (ft_err_node(*(nodes + i))) + return (1); + i++; + } + return (0); +} diff --git a/src/parser/parser_util_bonus.c b/src/parser/parser_util_bonus.c new file mode 100644 index 0000000..27f3aa8 --- /dev/null +++ b/src/parser/parser_util_bonus.c @@ -0,0 +1,136 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* parser_util_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: codespace +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/10/25 19:17:01 by jzubizar #+# #+# */ +/* Updated: 2023/11/13 10:01:42 by codespace ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../../inc/parse_bonus.h" + +//Returns the node quantity tto be allocated for the parsing of str +int ft_node_quant(char **str) +{ + int i; + int flag; + + i = 0; + flag = 0; + while (*str) + { + if (ft_strncmp(*str, "|", 2) && ft_strncmp(*str, "&&", 3) + && ft_strncmp(*str, "||", 3) && ft_strncmp(*str, "(", 2) + && ft_strncmp(*str, ")", 2)) + { + if (!flag) + { + flag = 1; + i++; + } + } + else + { + flag = 0; + i++; + } + str++; + } + return (i); +} + +//Returns value of how many different arguments +//do we have (including the cmd command) +int ft_num_args(char **str) +{ + int i; + + i = 0; + while (*str && ft_strncmp(*str, "|", 2) && ft_strncmp(*str, "&&", 3) + && ft_strncmp(*str, "||", 3) && ft_strncmp(*str, "(", 2) + && ft_strncmp(*str, ")", 2)) + { + if (!ft_strncmp(*str, ">>", 3) || !ft_strncmp(*str, ">", 2) + || !ft_strncmp(*str, "<<", 3) || !ft_strncmp(*str, "<", 3)) + { + if (*(str + 1)) + i -= 2; + else + i--; + } + i++; + str++; + } + return (i); +} + +//Function to fill the node type +//Rerturns 0 if it is a cmd, 1 if not +int ft_is_cm(char *str, t_px *node) +{ + if (!str) + return (1); + if (!ft_strcmp(str, "export") || !ft_strcmp(str, "cd") + || !ft_strcmp(str, "unset") || !ft_strcmp(str, "exit")) + return (node->type = BIp, 1); + else if (!ft_strcmp(str, "echo") || !ft_strcmp(str, "pwd") + || !ft_strcmp(str, "env")) + return (node->type = BIc, 1); + else if (!ft_strcmp(str, "&&")) + node->type = T_AND; + else if (!ft_strcmp(str, "||")) + node->type = T_OR; + else if (!ft_strcmp(str, "|")) + node->type = T_PIPE; + else if (!ft_strcmp(str, "(")) + node->type = L_PAR; + else if (!ft_strcmp(str, ")")) + node->type = R_PAR; + if (node->type != NONE) + return (2); + node->type = CMD; + return (0); +} + +char **ft_inout_file_condit(t_px *node, char **s, int *f) +{ + if (*s && (!ft_strncmp(*s, ">", 2) || !ft_strncmp(*s, ">>", 3) + || !ft_strncmp("<", *s, 2) || !ft_strncmp(*s, "<<", 3)) && ++(*f)) + { + if (!ft_strncmp("<", *s, 2)) + node->in_flag = 1; + else if (!ft_strncmp(*s, ">", 2)) + node->out_flag = 1; + else if (!ft_strncmp(*s, ">>", 3)) + node->out_flag = 2; + else + node->in_flag = 2; + s++; + if (*s && !ft_strchr("<|>", **s)) + { + if (node->out_flag) + node->outfile = ft_strdup(*s); + else if (node->in_flag == 1) + node->infile = ft_strdup(*(s)); + else if (node->in_flag == 2) + node->limit = ft_strdup(*(s)); + } + if (*s) + s++; + } + return (s); +} + +char **ft_inout_file(t_px *node, char **str) +{ + int flag; + + flag = 0; + str = ft_inout_file_condit(node, str, &flag); + if (flag) + str = ft_inout_file(node, str); + return (str); +} diff --git a/oldies/wildcard.c b/src/parser/wildcard_bonus.c similarity index 71% rename from oldies/wildcard.c rename to src/parser/wildcard_bonus.c index 576fc2b..6a8e6ec 100644 --- a/oldies/wildcard.c +++ b/src/parser/wildcard_bonus.c @@ -10,10 +10,7 @@ /* */ /* ************************************************************************** */ -#include"../inc/parse.h" -#include"../libft/libft.h" - - +#include "../../inc/parse_bonus.h" int ft_matlen(char **mat) { @@ -48,12 +45,13 @@ char **create_exp_cmdargs(char **cmdargs, int *size) char **exp_cmdargs; *size = (ft_matlen(cmdargs) * count_dir()) + 1; - exp_cmdargs = malloc(sizeof(char *) * *size); + exp_cmdargs = malloc(sizeof(char *) * (*size)); ft_bzero(exp_cmdargs, sizeof(char *) * (ft_matlen(cmdargs) * count_dir())); exp_cmdargs[0] = ft_strdup(cmdargs[0]); return (exp_cmdargs); } +//Returns 1 if there is a wildcard, 0 if not int find_wild_match(char *pattern, char *str) { while (*pattern) @@ -80,33 +78,33 @@ int find_wild_match(char *pattern, char *str) return (*str == '\0'); } -void fill_exp_cmdargs(char *pattern, char ***exp_cmdargs) +void fill_exp_cmdargs(char *pattern, char ***exp_cmdargs, int *j) { - static int j = 1; DIR *dir; struct dirent *entry; dir = opendir("."); entry = readdir(dir); while (entry != NULL) - { + { if (!ft_strcmp("*", pattern)) { if (entry->d_name[0] != '.') { - (*exp_cmdargs)[j] = ft_strdup(entry->d_name); - j++; + (*exp_cmdargs)[*j] = ft_strdup(entry->d_name); + (*j)++; } } else if (find_wild_match(pattern, entry->d_name)) { - (*exp_cmdargs)[j] = ft_strdup(entry->d_name); - j++; + (*exp_cmdargs)[*j] = ft_strdup(entry->d_name); + (*j)++; } entry = readdir(dir); } closedir(dir); } + char **trim_excess(char **exp, int size) { char **trim; @@ -118,57 +116,45 @@ char **trim_excess(char **exp, int size) trim = malloc(sizeof(char *) * (len + 1)); trim[len] = NULL; i = 0; - printf("len: %i\n", len); while (i < len) { trim[i] = ft_strdup(exp[i]); i++; } ft_free_split(exp); - return (trim); + return (trim); } - -void ft_wildcard(char ***cmdargs) +void ft_wildcard(t_px *node) { int i; int size; char **exp_cmdargs; - char **exp_trim; + int j; - i = 1; - exp_cmdargs = create_exp_cmdargs(*cmdargs, &size); - while ((*cmdargs)[i]) + i = 0; + if (!node->full_cmd) + return ; + j = 1; + exp_cmdargs = create_exp_cmdargs(node->full_cmd, &size); + while ((node->full_cmd)[++i]) { - if (ft_strchr((*cmdargs)[i], '*')) - fill_exp_cmdargs((*cmdargs)[i], &exp_cmdargs); - i++; + if (ft_strchr((node->full_cmd)[i], '*')) + fill_exp_cmdargs((node->full_cmd)[i], &exp_cmdargs, &j); + else + exp_cmdargs[j++] = ft_strdup((node->full_cmd)[i]); } - - - - - exp_trim = trim_excess(exp_cmdargs, size); - + exp_cmdargs = trim_excess(exp_cmdargs, size); i = 0; - while (exp_trim[i]) - { - printf("el cmdargs expandido %i : %s\n", i, exp_trim[i]); - i++; - } -/* while (exp_cmdargs[i]) + while (exp_cmdargs[i]) { - printf("el cmdargs expandido %i : %s\n", i, exp_cmdargs[i]); i++; - } */ - //liberar cmdargs; - ft_free_split(*cmdargs); - - //cmdargs = exp_cmdargs; - ft_free_split(exp_trim); //este es el bueno + } + ft_free_split(node->full_cmd); + node->full_cmd = exp_cmdargs; } -int main() +/*int main() { char **cmdargs; @@ -182,4 +168,4 @@ int main() ft_wildcard(&cmdargs); ft_free_split(cmdargs); return (0); -} +}*/ diff --git a/src/splitstr/check_var.c b/src/splitstr/check_var.c index 527ee57..076f96d 100644 --- a/src/splitstr/check_var.c +++ b/src/splitstr/check_var.c @@ -3,10 +3,10 @@ /* ::: :::::::: */ /* check_var.c :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: jzubizar +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/10/05 10:43:53 by jzubizar #+# #+# */ -/* Updated: 2023/11/02 09:46:37 by jzubizar ### ########.fr */ +/* Updated: 2023/11/13 10:37:52 by codespace ### ########.fr */ /* */ /* ************************************************************************** */ @@ -170,7 +170,7 @@ int ft_check_var(char **str, char **env) quote = 0; i = 0; while (*str && (*str)[i]) - { + { if ((*str)[i] == '"') { i++; diff --git a/src/splitstr/correc_special.c b/src/splitstr/correc_special.c index e0df8bf..e4e8eb6 100644 --- a/src/splitstr/correc_special.c +++ b/src/splitstr/correc_special.c @@ -3,10 +3,10 @@ /* ::: :::::::: */ /* correc_special.c :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: imontero +#+ +:+ +#+ */ +/* By: codespace +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/10/10 16:39:38 by josu #+# #+# */ -/* Updated: 2023/10/31 11:44:36 by imontero ### ########.fr */ +/* Updated: 2023/11/13 10:38:34 by codespace ### ########.fr */ /* */ /* ************************************************************************** */ @@ -30,7 +30,7 @@ static int ft_correc_len(char **str, char *spec) str++; } return (len); -} +} char *ft_fill_wrd(char *str) { @@ -85,7 +85,7 @@ static int ft_correc_fill(char **res, char **str, char *spec) free(str_mem); res[len] = NULL; return (0); -} +} char **ft_correc_special(char **str, char *spec) { diff --git a/src/splitstr/split.c b/src/splitstr/split.c index 5d04ae0..d9d0563 100644 --- a/src/splitstr/split.c +++ b/src/splitstr/split.c @@ -3,10 +3,10 @@ /* ::: :::::::: */ /* split.c :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: jzubizar +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/10/03 17:14:34 by jzubizar #+# #+# */ -/* Updated: 2023/11/02 09:11:49 by jzubizar ### ########.fr */ +/* Updated: 2023/11/03 09:47:27 by codespace ### ########.fr */ /* */ /* ************************************************************************** */ diff --git a/src/splitstr/split_bonus.c b/src/splitstr/split_bonus.c new file mode 100644 index 0000000..00d6be3 --- /dev/null +++ b/src/splitstr/split_bonus.c @@ -0,0 +1,141 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* split_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: codespace +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/10/03 17:14:34 by jzubizar #+# #+# */ +/* Updated: 2023/11/03 09:47:19 by codespace ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../../inc/parse.h" + +/* Sub function for ft_split_str */ +static int ft_split_low(char **split, char const *s, char c) +{ + char *str; + char *word; + int len; + int i; + + str = (char *)s; + i = 0; + while (i < ft_nbr_wrd(s, c)) + { + len = ft_str_chlen(str, c); + if (len > 0) + { + word = malloc(sizeof(char) * (len + 1)); + if (word == NULL) + return (i + 1); + word = ft_fill_word(word, str, len); + split[i] = word; + str += len + 1; + i++; + } + else + str++; + } + split[ft_nbr_wrd(s, c)] = NULL; + return (0); +} + +//Splits a String into a 2D string array, taking quotes into account" +char **ft_split_str(char const *s, char c) +{ + char **split; + int err; + int i; + + if (!ft_nbr_wrd(s, c)) + return (NULL); + split = malloc(sizeof(char *) * (ft_nbr_wrd(s, c) + 1)); + if (split == NULL) + return (ft_error(MEM, NULL, 2)); + err = ft_split_low(split, s, c); + if (err) + { + i = 0; + while (i < err - 1) + { + free(split[i]); + i++; + } + free (split); + return (ft_error(MEM, NULL, 2)); + } + return (split); +} + +//Returns the length of the corrected string fot ft_correct_str +int ft_strcorr_len(char *str, char *act) +{ + unsigned int i; + int extra; + + i = 0; + extra = 0; + while (str[i]) + { + ft_mv_in_quotes(str, &i); + if (ft_strchr(act, str[i])) + extra += 2; + if (str[i]) + i++; + } + return (i + extra); +} + +//Auxiliar function of correct string, with the conditional statements +void ft_aux_correct_str(char *res, char *str, int *i, int *extra) +{ + char quote; + + if (str[*i] == '\"' || str[*i] == '\'') + { + quote = str[*i]; + res[*i + *extra] = str[*i]; + (*i)++; + while (str[*i]) + { + res[*i + *extra] = str[*i]; + if (str[*i] == quote) + break ; + (*i)++; + } + } + if (ft_strchr("<>|&()", str[*i])) + { + res[*i + *extra] = ' '; + res[*i + *extra + 1] = str[*i]; + res[*i + *extra + 2] = ' '; + (*extra) += 2; + } + else + res[*i + *extra] = str[*i]; +} + +//Adds spaces into the string, separating the special characters +// str is freed in terminal function +char *ft_correct_str(char *str) +{ + char *res; + int i; + int extra; + + i = 0; + extra = 0; + res = malloc(ft_strcorr_len(str, "<>|&()") + 1); + if (!res) + return (ft_error(MEM, NULL, 2)); + while (str[i]) + { + ft_aux_correct_str(res, str, &i, &extra); + if (str[i]) + i++; + } + res[i + extra] = '\0'; + return (res); +} diff --git a/src/terminal/terminal.c b/src/terminal/terminal.c index 420413d..d9f0fa0 100644 --- a/src/terminal/terminal.c +++ b/src/terminal/terminal.c @@ -3,10 +3,10 @@ /* ::: :::::::: */ /* terminal.c :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: imontero +#+ +:+ +#+ */ +/* By: codespace +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/10/14 18:49:26 by josu #+# #+# */ -/* Updated: 2023/10/31 13:11:08 by imontero ### ########.fr */ +/* Updated: 2023/11/13 10:46:43 by codespace ### ########.fr */ /* */ /* ************************************************************************** */ @@ -115,7 +115,7 @@ void ft_set_sig(void) sigaction(SIGINT, &sa, NULL); sa.sa_handler = SIG_IGN; sigaction(SIGQUIT, &sa, NULL); -} +} //void terminal(char **env) void terminal(t_info *info) @@ -132,7 +132,7 @@ void terminal(t_info *info) break ; terminal_options(input); if (ft_strlen(input)) - { + { if (ft_lines(input, info) == 4) { free(input); diff --git a/src/terminal/terminal_bonus.c b/src/terminal/terminal_bonus.c new file mode 100644 index 0000000..ad63fb5 --- /dev/null +++ b/src/terminal/terminal_bonus.c @@ -0,0 +1,209 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* terminal_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: codespace +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/10/14 18:49:26 by josu #+# #+# */ +/* Updated: 2023/11/14 10:50:45 by codespace ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../../inc/parse_bonus.h" + +int ft_lines2(char *str, t_info *info, char ***res) +{ + str = ft_correct_str(str); + if (!str) + return (1); + *res = ft_split_str(str, ' '); + free (str); + if (!(*res)) + return (2); + if (ft_check_var(*res, info->envcp)) + return (ft_free_split(*res), 3); + *res = ft_correc_special(*res, "<>|&"); + if (!(*res)) + return (3); + return (0); +} + +void ft_open_outfiles(t_px *nodes) +{ + int i; + int fd; + + i = 0; + while (i < nodes->info->cmd_amount) + { + if (nodes[i].outfile) + { + fd = open(nodes[i].outfile, O_CREAT | O_WRONLY | O_TRUNC, 0644); + close(fd); + } + i++; + } +} + +//Function to advance i to the next possibly eectuable command +void ft_advance_unused(t_px *nodes, int *i) +{ + int par; + + par = 0; + if (nodes[*i].type == L_PAR) + { + par = 1; + (*i)++; + while (*i < nodes->info->cmd_amount && par) + { + if (nodes[*i].type == L_PAR) + par++; + else if (nodes[*i].type == R_PAR) + par--; + (*i)++; + } + (*i)++; + } + else if (*i < nodes->info->cmd_amount) + *i += nodes[*i].cmd_real_num; +} + +//Function to execute pipex repeatedly deppending on +//commands &&, || and () +void ft_loop_pipex(t_px *nodes, int *i) +{ + t_type tp; + + while (*i < nodes->info->cmd_amount) + { + tp = nodes[*i].type; + if (tp == L_PAR || tp == R_PAR || tp == T_AND || tp == T_OR) + (*i)++; + if (tp == L_PAR) + { + ft_loop_pipex(nodes, i); + continue ; + } + else if (tp == R_PAR) + return ; + else if ((tp == T_AND && g_stat == 0) || (tp == T_OR && g_stat != 0)) + continue ; + else if ((tp == T_AND && g_stat != 0) || (tp == T_OR && g_stat == 0)) + { + ft_advance_unused(nodes, i); + continue ; + } + pipex(&nodes[*i]); + *i += nodes[*i].cmd_real_num; + } +} + +//int ft_lines(char *str, char **env) +int ft_lines(char *str, t_info *info) +{ + char **res; + t_px *nodes; + int i; + + if (ft_lines2(str, info, &res)) + return (1); + if (!ft_clean_quotes(res)) + return (ft_free_split(res), 1); + nodes = ft_parse(res, info); + ft_free_split(res); + if (!nodes) + return (1); + if (nodes->info->cmd_amount == 1 && nodes->type == BIp) + { + if (ft_execbi_parent(nodes)) + { + ft_free_nodes(nodes); + return (4); + } + } + ft_open_outfiles(nodes); + i = 0; + ft_loop_pipex(nodes, &i); + ft_free_nodes(nodes); + return (0); +} + +/* + returns custom prompt with user or just std prompt if user is suppresed. + NULL if error +*/ +char *get_prompt(char **env) +{ + int i; + int found; + char *user; + char *prompt; + + i = 0; + found = 0; + while (env[i]) + { + if (ft_strnstr(env[i], "USER=", 5)) + { + user = ft_strjoin(BLUEB, env[i] + 5); + if (user) + found++; + break ; + } + i++; + } + if (found == 0) + { + prompt = ft_strdup(GREENB"minichel42 "X); + return (prompt); + } + prompt = ft_strjoin(user, GREENB"@minichel42 "X); + return (free(user), prompt); +} + +void ft_set_sig(void) +{ + struct sigaction sa; + + sa.sa_handler = &ft_handle_client; + sigaction(SIGINT, &sa, NULL); + sa.sa_handler = SIG_IGN; + sigaction(SIGQUIT, &sa, NULL); +} + +//void terminal(char **env) +void terminal(t_info *info) +{ + char *input; + char *prompt; + + prompt = get_prompt(info->envcp); + while (1) + { + ft_set_sig(); + input = readline(prompt); + if (!input) + break ; + terminal_options(input); + if (ft_strlen(input)) + { + if (ft_lines(input, info) == 4) + { + free(input); + break ; + } + } + free (input); + } + free(prompt); +} + +void terminal_options(char *input) +{ + if (input[0]) + add_history(input); + if (!ft_strcmp("clear", input)) + printf("\033[H\033[2J"); +}