diff --git a/42sh/.gitignore b/42sh/.gitignore index a0b5f8cc..77f4c561 100644 --- a/42sh/.gitignore +++ b/42sh/.gitignore @@ -2,6 +2,7 @@ minishell 21sh 42sh out +STDBUG debug .42sh_history *.dSYM diff --git a/42sh/Makefile b/42sh/Makefile index 1f930775..c5061dff 100644 --- a/42sh/Makefile +++ b/42sh/Makefile @@ -1,14 +1,14 @@ -#* ************************************************************************** *# -#* *# -#* ::: :::::::: *# -#* Makefile :+: :+: :+: *# -#* +:+ +:+ +:+ *# -#* By: wescande +#+ +:+ +#+ *# -#* +#+#+#+#+#+ +#+ *# -#* Created: 2016/08/29 21:32:58 by wescande #+# #+# *# -#* Updated: 2016/09/27 20:14:55 by wescande ### ########.fr *# -#* *# -#* ************************************************************************** *# +# **************************************************************************** # +# # +# ::: :::::::: # +# Makefile :+: :+: :+: # +# +:+ +:+ +:+ # +# By: wescande +#+ +:+ +#+ # +# +#+#+#+#+#+ +#+ # +# Created: 2016/08/29 21:32:58 by wescande #+# #+# # +# Updated: 2017/02/20 20:02:23 by ariard ### ########.fr # +# # +# **************************************************************************** # NAME = 42sh @@ -36,38 +36,70 @@ builtin/builtin_cd.c\ builtin/builtin_echo.c\ builtin/builtin_env.c\ builtin/builtin_exit.c\ +builtin/builtin_export.c\ +builtin/builtin_hash.c\ +builtin/builtin_history.c\ builtin/builtin_read.c\ builtin/builtin_setenv.c\ +builtin/builtin_unset.c\ builtin/builtin_unsetenv.c\ builtin/is_builtin.c\ +completion/c_binary.c\ +completion/c_clear.c\ +completion/c_files.c\ +completion/c_init.c\ +completion/c_matching.c\ +completion/c_misc.c\ +completion/c_output.c\ +completion/c_parser.c\ +completion/c_pathsolver.c\ +completion/c_printer.c\ +completion/c_rematch.c\ +completion/c_sizing.c\ +completion/c_terminal.c\ +completion/completion.c\ exec/ast_free.c\ +exec/bad_fd.c\ exec/exec_ampersand.c\ exec/exec_and_if.c\ exec/exec_command.c\ exec/exec_default.c\ -exec/exec_dgreat.c\ -exec/exec_great.c\ +exec/exec_elif.c\ +exec/exec_else.c\ +exec/exec_if.c\ exec/exec_less.c\ exec/exec_or_if.c\ exec/exec_pipe.c\ +exec/exec_redir.c\ exec/exec_semi.c\ -exec/exec_while.c\ -exec/exec_if.c\ -exec/exec_else.c\ -exec/exec_elif.c\ exec/exec_until.c\ +exec/exec_while.c\ +exec/fd_is_valid.c\ exec/ft_exec.c\ exec/ft_findexec.c\ exec/launch_process.c\ +exec/loop_del.c\ +exec/loop_exec.c\ exec/process_redirect.c\ exec/process_reset.c\ +exec/process_resetfds.c\ exec/process_setexec.c\ exec/process_setgroup.c\ exec/process_setsig.c\ +exec/redirect_dgreat.c\ +exec/redirect_dless.c\ +exec/redirect_great.c\ +exec/redirect_greatand.c\ +exec/redirect_less.c\ +exec/redirect_lessand.c\ exec/set_exitstatus.c\ +glob/command_getoutput.c\ glob/dir_glob.c\ +glob/esc_print.c\ +glob/expand_bquote.c\ glob/expand_brace.c\ glob/expand_esc.c\ +glob/expand_var.c\ glob/ft_strsplit_esc.c\ glob/ft_strsplit_spe.c\ glob/glob.c\ @@ -84,10 +116,24 @@ glob/lib_perso/ft_ld_reverse.c\ glob/lib_perso/ft_ld_size.c\ glob/lib_perso/ft_ld_swap.c\ glob/lib_perso/ft_ld_to_tab.c\ +glob/lib_perso/ft_memrealloc.c\ glob/lib_perso/ft_strjoinf.c\ +glob/lib_perso/ft_strsubf.c\ glob/lib_perso/ft_tabdel.c\ glob/lib_perso/ft_tablen.c\ glob/match_pattern.c\ +hash_table/ft_add_hash.c\ +hash_table/hash.c\ +hash_table/hash_free.c\ +hash_table/hash_str.c\ +hash_table/is_hash.c\ +history/add_str_in_history.c\ +history/history.c\ +history/history_parsing.c\ +history/history_parsing_toolz.c\ +history/history_parsing_toolz_2.c\ +history/list_toolz.c\ +history/surch_in_history.c\ job-control/builtin_bg.c\ job-control/builtin_fg.c\ job-control/builtin_jobs.c\ @@ -121,37 +167,65 @@ job-control/sigint_handler.c\ job-control/sigtstp_handler.c\ job-control/sigttin_handler.c\ job-control/sigttou_handler.c\ -lexer/command_getoutput.c\ -lexer/ft_lexer.c\ +lexer/.ft_post_tokenize.c.swp\ +lexer/.ft_tokenize.c.swp\ +lexer/.reduce_bquotes.c.swp\ lexer/ft_post_tokenize.c\ -lexer/ft_tokenize.c\ -lexer/get_lexer_state.c\ +lexer/get_lexer_stack.c\ lexer/get_reserved_words.c\ +lexer/get_state_global.c\ +lexer/get_state_redir.c\ lexer/lexer_backslash.c\ +lexer/lexer_bquote.c\ lexer/lexer_comment.c\ +lexer/lexer_comment.c~HEAD\ lexer/lexer_default.c\ lexer/lexer_delim.c\ +lexer/lexer_dless.c\ lexer/lexer_dquote.c\ +lexer/lexer_end.c\ lexer/lexer_great.c\ lexer/lexer_greatand.c\ +lexer/lexer_init.c\ lexer/lexer_less.c\ lexer/lexer_lessand.c\ +lexer/lexer_lex.c\ lexer/lexer_newline.c\ +lexer/lexer_newline.c~HEAD\ lexer/lexer_number.c\ +lexer/lexer_paren.c\ lexer/lexer_quote.c\ lexer/lexer_sep.c\ lexer/lexer_special.c\ lexer/lexer_then.c\ -lexer/lexer_var.c\ lexer/lexer_word.c\ lexer/reduce_bquotes.c\ lexer/reduce_parens.c\ +lexer/stack_to_prompt.c\ lexer/token_append.c\ lexer/token_cmp_type.c\ -lexer/token_expand_var.c\ lexer/token_free.c\ lexer/token_init.c\ lexer/token_print.c\ +line-editing/completion.c\ +line-editing/control_c_and_d.c\ +line-editing/copy_cut_paste.c\ +line-editing/ft_prompt.c\ +line-editing/get_key.c\ +line-editing/home_end.c\ +line-editing/lib_line_editing/tool_line.c\ +line-editing/lib_line_editing/tool_line_2.c\ +line-editing/lib_line_editing/toolz.c\ +line-editing/lib_line_editing/toolz2.c\ +line-editing/lib_line_editing/toolz_parseur.c\ +line-editing/lib_line_editing/toolz_termcaps.c\ +line-editing/move_left_and_right.c\ +line-editing/move_to_word.c\ +line-editing/move_up_and_down.c\ +line-editing/print_and_del.c\ +line-editing/queue.c\ +line-editing/readline.c\ +main/.main.c.swp\ main/data_exit.c\ main/data_init.c\ main/data_singleton.c\ @@ -162,46 +236,55 @@ main/ft_putast2.c\ main/lib_expansion.c\ main/main.c\ main/read_script.c\ +main/remove_trailing_esc_nl.c\ main/shell_exit.c\ main/shell_get_avdata.c\ main/shell_get_opts.c\ main/shell_init.c\ main/shell_script.c\ main/sig_handler.c\ -parser/old_parse.c\ +parser/.eval_sym.c.swo\ +parser/.eval_sym.c.swp\ +parser/.ft_parse.c.swo\ +parser/.produce_sym.c.swo\ +parser/.produce_sym.c.swp\ +parser/.read_stack.c.swo\ +parser/.read_stack.c.swp\ +parser/add_cmd.c\ +parser/add_condition.c\ +parser/add_file.c\ +parser/add_loop.c\ +parser/add_sep.c\ +parser/aggregate_sym.c\ +parser/build_tree.c\ +parser/error_syntax.c\ +parser/eval_sym.c\ +parser/ft_parse.c\ parser/get_instruction.c\ parser/get_sub_instruction.c\ +parser/old_parse.c\ +parser/parse.c\ parser/parse_dgreat.c\ parser/parse_dless.c\ parser/parse_do.c\ parser/parse_done.c\ +parser/parse_elif.c\ +parser/parse_else.c\ parser/parse_great.c\ parser/parse_greatand.c\ +parser/parse_if.c\ parser/parse_less.c\ parser/parse_lessand.c\ +parser/parse_redir.c\ parser/parse_separator.c\ parser/parse_subshell.c\ parser/parse_while.c\ -parser/parse_if.c\ -parser/parse_elif.c\ -parser/parse_else.c\ parser/parse_word.c\ -parser/read_stack.c\ -parser/parse.c\ -parser/ft_parse.c\ -parser/produce_sym.c\ -parser/eval_sym.c\ -parser/aggregate_sym.c\ parser/pop_stack.c\ +parser/produce_sym.c\ parser/push_stack.c\ -parser/error_syntax.c\ -parser/build_tree.c\ -parser/tree_wrapper.c\ -parser/add_sep.c\ -parser/add_cmd.c\ -parser/add_file.c\ -parser/add_loop.c\ -parser/add_condition.c +parser/read_stack.c\ +parser/tree_wrapper.c SRCS = $(addprefix $(SRC_DIR), $(SRC_BASE)) OBJS = $(addprefix $(OBJ_DIR), $(SRC_BASE:.c=.o)) @@ -218,10 +301,10 @@ $(NAME): $(LIBFT_LIB) $(OBJ_DIR) $(OBJS) $(LIBS) \ $(LIBFT_LIB) $(OBJS) \ -o $(NAME) - @echo "\r\033[48;5;15;38;5;25m✅ MAKE $(NAME)\033[0m\033[K" + @printf "\r\e[48;5;15;38;5;25m✅ MAKE $(NAME)\e[0m\e[K\n" $(LIBFT_LIB): - @make -j -C $(LIBFT_DIR) + @make -C $(LIBFT_DIR) $(OBJ_DIR) : @mkdir -p $(OBJ_DIR) @@ -232,22 +315,22 @@ $(OBJ_DIR)%.o : $(SRC_DIR)%.c | $(OBJ_DIR) @$(eval PERCENT=$(shell echo $$(($(INDEX)*100/$(NB))))) @$(eval COLOR=$(shell echo $$(($(PERCENT)%35+196)))) @$(eval TO_DO=$(shell echo $$((20-$(INDEX)*20/$(NB))))) - @printf "\r\033[38;5;11m⌛ MAKE %10.10s : %2d%% \033[48;5;%dm%*s\033[0m%*s\033[48;5;255m \033[0m \033[38;5;11m %*s\033[0m\033[K" $(NAME) $(PERCENT) $(COLOR) $(DONE) "" $(TO_DO) "" $(DELTA) "$@" - @$(CC) $(FLAGS) -MMD -c $< -o $@\ + @printf "\r\e[38;5;11m⌛ MAKE %10.10s : %2d%% \e[48;5;%dm%*s\e[0m%*s\e[48;5;255m \e[0m \e[38;5;11m %*s\e[0m\e[K" $(NAME) $(PERCENT) $(COLOR) $(DONE) "" $(TO_DO) "" $(DELTA) "$@" + @$(CC) $(FLAGS) $(D_FLAGS) -MMD -c $< -o $@\ -I $(INC_DIR)\ -I $(LIBFT_INC) @$(eval INDEX=$(shell echo $$(($(INDEX)+1)))) clean: cleanlib @rm -rf $(OBJ_DIR) - @echo "\r\033[38;5;202m✖ clean $(NAME).\033[0m\033[K" + @printf "\r\e[38;5;202m✖ clean $(NAME).\e[0m\e[K\n" cleanlib: @make -C $(LIBFT_DIR) clean fclean: clean fcleanlib @rm -f $(NAME) - @echo "\r\033[38;5;196m❌ fclean $(NAME).\033[0m\033[K" + @printf "\r\e[38;5;196m❌ fclean $(NAME).\e[0m\e[K\n" fcleanlib: cleanlib @make -C $(LIBFT_DIR) fclean diff --git a/42sh/donovan_segaults_06-02 b/42sh/donovan_segaults_06-02 new file mode 100644 index 00000000..f8217daf --- /dev/null +++ b/42sh/donovan_segaults_06-02 @@ -0,0 +1,533 @@ +ls +cat +`ls` +` +`ls` +`ls` +`ls` +cat * +ls * +echo "*" +echo * +echo */* +ls +make +make +ls +ls | cat +ls | cat -e +`ls` +`ls` +`ls` +`ls` +`ls` +`ls` +`ls` +`ls` +ls +`ls` +echo `ls -l` +(ls) +`ls` +` +`ls` +` +` +` +` +` +` +(ls)) +(ls)) +(ls)) +` +( +`ls` +`ls` +`ls` +ls +` +ls +`ls` +` +) +(vim)) +ls +`ls` +`l` +ls +ls +ls +`ls` +ls +`ls` +ls m +ls m 2>/dev/null +ls +ls >/dev/null +ls m +ls m 2>&1 +ls m +ls m >/dev/null +ls m 2>/dev/null +ls m 2>&- +ls m +ls m 2>&- +ls +ls 1>/dev/null +ls merde +ls merde 2>/dev/null +ls merde 1>/dev/null +ls merde 3>/dev/null +ls merde 2>/dev/null +ls 2>/dev/null +ls +ls >/dev/null +ls >/dev/null +ls >/dev/null +ls >/dev/null +ls >/dev/null +ls >/dev/null +ls 1>/dev/null +ls 1>/dev/null +ls merde +ls merde >/dev/null +ls merde 2>/dev/null +ls merde 2>&- +ls merde 2<&- +ls merde 2<&- +ls merde 2<&- +ls +ls >&- +ls >&- +ls 2>&- +ls m 2>&- +ls +ls 1>&2 2>&- +ls 2>&- 1>&2 +ls 2>&- 1>&2 +ls 1>&2 2>&- +ls 1>&2 2>&- +ls 2>&- 1>&2 +ls 1>&2 +ls 1>&2 1>&- +ls 1>&- 1>&2 +ls 2>&- 1>&2 +ls 1>&- 2>&- +ls 1>&2- 2>&- +ls 1>&2 2>&- +ls 2>&- 1>&2 +ls 1>&2- +ls 1>&2 +ls 1>&2 1>&- +ls 1>&- 1>&2 +ls 1>&- 1>&2 +ls 2>&- +ls 2>&- 1>&- +ls 2>&- 1>&2 +ls 2>&- 1>&2 +ls 2>&- 1>&2 +ls 2>&- 1>&2 +ls 2>&- 1>&- +ls 2>&- 1>&- +ls 2>&- 1>&2 +ls 1>&2 2>&- + +ls +ls 2>&- +ls 2>&- 1>&2 +ls + +ls + +ls + +ls + ls +ls + ls + ls + + + ls +ls + +ls + + + + + + ls + +`ls` +` ` +`` `` +echo `ls``ls` +echo `ls` `ls` +`ls``ls` +a`ls` +`ls`` +`ls``ls` +`` +``` +```` +`` ``` +`` `` +```` +`` +`` +` +`` +ls +`` +` +make +`` +```` +`` `` +```` +`` `` +` +`` +```` +`` `` +```` +`` +`` +```` +```` +```` +```` +a`ls` echo `ls` +echo `ls` +echo `ls` +a`ls` +a`ls` +a`ls` +a`ls` +a`ls` +a`ls | wc` +ls + ls + ls +ls | cat + + +ls + +`` +` ` +```` +`` `` +cd +ls +alalalalal`ls` + + + 1 + ` + `` + ` ` +(vim)& `ls` +jobs +fg +fg +jobs -l +kill -9 80401 +jobs +jobs +fg +vim& +jobs +ls +vim& +ls& +jobs +fg +jobs +ls& +jobs +jobs -l +ls +ls& +jobs +vim +jobs +jobs +ls +ls& +jobs +ls& +jobs +vim& +fg +ls +a`la` +ls + +ls +ls + + +```` ```` `` +ls + +ls +ls >&- +ls >&waf- +ls >&24- +ls +{} +{()} +({}) +{(ls)} +() +ls +read -n 4 +read -n 5 +echo $REPLY +read -n 4 +l +read -n 4 +read - n5 +read -n 5 +echo $REPLY | cat -e +echo $REPLY +read -n 5 +echo $REPLY +read -n 3 +echo $REPLY +read -n 3 +echo $REPLY +read -n -s +read -n 2 -s +read -s +ls +read -n 3 +echo $REPLY +echo $REPLY | cat -e +echo $PATH +read -n 10 +echo $REPLY +read -n 10 +echo $REPLY +(ls) +(ls)l +(ls) +(ls)l +(ls) +(ls)l +{()} +{} +42sh_cpy > wc -l < Makefile +42sh_cpy > wc -l > Makefile +wc -l < Makefile +cat out1 +ls out +ls < out +ls > out +ls < out +ls>out +lsout +lsout +lsout +lsout +lsout +cat out +lsout +lsout +lsout +cat out +ls>out +lsout +rm out +ls >out +ls -l +ls out +ls +lsout +lsout +cat out +ls>out +make +ls>out +ls&- +ls +ls >&2 2>&- +ls > out +rm out +ls > out +ls -l +ls >out +; +l +ls +ls>out +cat out +wc -l out +ls -l >out +catout +cat out +cat out +lsout +lsout +wc -l file1 +cat file1 +cat file1 +cat file1 +cat out +wc -l &- 1>&2 +cat +cat /dev/random|base64|head -c 8 & +cat /dev/random|base64|head -c 8 +ls +stty +stty -a +ls +cat +ls 'abc +def' +ls 'abc +' +ls >&- +ls 2>&- +ls mm 2>&- +ls mm 2>&- +cd >&- +./a.out +ls +./a.out +./42sh +pwd +/Users/jhalford/minishell/a.out +ls | /Users/jhalford/minishell/a.out +/a | cat /dev/random | base64 > /dev/null +./42sh +sleep 66666 & +jobs +echo '\ + +' +ls \ + +ls '\' +ls "\" +\ + +\ +\ +\ +\ +\\ +\\ +abc\ +def +l\ +s +ls 3>&- +ls >&3 +ls -- -1>file3 +ls -- 9>file3 +ls -- 10>file3 +ls -- 9999999999999999999999999999999999999999999999999999999>file3 +ls -- 2147483648>file3 +ls -- 2147483647>file3 +ls -- >&2147483648 +ls -- >&2147483649 +ulimit -a +& +\\ \ \\\ +${$(})} ${$((}))} ${`}`} ${${a}} +( ls # ) +ls&&ls;ls||ls; +ls&&ls;ls||ls +echo a && echo b; +echo a || echo b; +echo a ||; echo b; +echo a; || echo b; +(ls;) ; +ls ;; ls +` ( echo "(ls" )` +` ( echo "(ls(" )` +` ( echo "(ls((" )` +`echo "ls -l"` +` echo "ls `echo .`"` diff --git a/42sh/includes/btree.h b/42sh/includes/btree.h deleted file mode 100644 index 5839155c..00000000 --- a/42sh/includes/btree.h +++ /dev/null @@ -1,54 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* btree.h :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: jhalford +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2016/11/16 11:13:15 by jhalford #+# #+# */ -/* Updated: 2016/12/05 11:53:30 by jhalford ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#ifndef BTREE_H -# define BTREE_H - -# include "libft.h" - -struct s_btree -{ - void *item; - size_t content_size; - struct s_btree *left; - struct s_btree *right; -}; - -struct s_printdata -{ - int is_left; - int offset; - int depth; - int left; - int right; -}; - -typedef struct s_btree t_btree; -typedef struct s_printdata t_printdata; - -t_btree *btree_create_node(void const *item, size_t content_size); -void btree_insert_data( - t_btree **root, - void *item, - size_t content_size, - int (*cmpf)(void *, void *)); -void *btree_search_item(t_btree *root, - void *data_ref, int (*cmpf)(void *, void *)); -int btree_level_count(t_btree *root); -void btree_apply_prefix(t_btree *root, void (*applyf)(void *)); -void btree_apply_infix(t_btree *root, void (*applyf)(void *)); -void btree_apply_suffix(t_btree *root, void (*applyf)(void *)); -void btree_print(int fd, t_btree *tree, char *(*printer)(void *)); -void btree_del(t_btree **root, void (*del)(void *, size_t)); -void btree_delone(t_btree **root, void (*del)(void *, size_t)); - -#endif diff --git a/42sh/includes/builtin.h b/42sh/includes/builtin.h index 265c5f9c..61336315 100644 --- a/42sh/includes/builtin.h +++ b/42sh/includes/builtin.h @@ -6,7 +6,7 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/12/13 17:21:56 by jhalford #+# #+# */ -/* Updated: 2017/02/03 14:44:09 by ariard ### ########.fr */ +/* Updated: 2017/02/20 20:21:05 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ @@ -18,6 +18,8 @@ # include "builtin_read.h" t_execf *is_builtin(t_process *p); +int builtin_export(const char *path, char *const av[], char *const envp[]); +int builtin_unset(const char *path, char *const av[], char *const envp[]); int builtin_env(const char *path, char *const argv[], char *const envp[]); int builtin_echo(const char *path, char *const argv[], char *const envp[]); int builtin_cd(const char *path, char *const argv[], char *const envp[]); @@ -28,5 +30,6 @@ int builtin_jobs(const char *path, char *const av[], char *const envp[]); int builtin_fg(const char *path, char *const av[], char *const envp[]); int builtin_bg(const char *path, char *const av[], char *const envp[]); int builtin_history(const char *path, char *const av[], char *const envp[]); +int builtin_hash(const char *path, char *const av[], char *const envp[]); #endif diff --git a/42sh/includes/builtin_read.h b/42sh/includes/builtin_read.h index 177f9176..bb8256a8 100644 --- a/42sh/includes/builtin_read.h +++ b/42sh/includes/builtin_read.h @@ -6,7 +6,7 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2017/01/20 15:02:39 by jhalford #+# #+# */ -/* Updated: 2017/01/27 18:56:58 by jhalford ### ########.fr */ +/* Updated: 2017/02/03 15:59:15 by jhalford ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,7 +14,6 @@ # define BUILTIN_READ_H # include "types.h" -# include "libft.h" # include "builtin.h" # include "minishell.h" diff --git a/42sh/includes/color.h b/42sh/includes/color.h deleted file mode 100644 index 96eea18e..00000000 --- a/42sh/includes/color.h +++ /dev/null @@ -1,56 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* color.h :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: jhalford +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2016/11/25 13:36:48 by jhalford #+# #+# */ -/* Updated: 2016/12/09 22:09:24 by jhalford ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#ifndef COLOR_H -# define COLOR_H -# include "libft.h" - -struct s_color -{ - char fg[7]; - char bg[7]; -}; - -typedef struct s_color t_color; - -# define FG_DEFAULT "\x1b[0m" -# define ON_BOLD "\x1b[1m" - -# define ON_UNDERLINED "\x1b[4m" -# define ON_INVERTED "\x1b[7m" - -# define FG_BLACK "\x1b[30m" -# define FG_RED "\x1b[31m" -# define FG_GREEN "\x1b[32m" -# define FG_YELLOW "\x1b[33m" -# define FG_BLUE "\x1b[34m" -# define FG_MAGENTA "\x1b[35m" -# define FG_CYAN "\x1b[36m" - -# define BG_BLACK "\x1b[40m" -# define BG_RED "\x1b[41m" -# define BG_GREEN "\x1b[42m" -# define BG_YELLOW "\x1b[43m" -# define BG_BLUE "\x1b[44m" -# define BG_MAGENTA "\x1b[45m" -# define BG_CYAN "\x1b[46m" -# define BG_DEFAULT "\x1b[49m" - -# define FBG_DEFAULT "\x1b[49m\x1b[20m" - -void ft_color_reset(void); -void ft_color_set(t_color color); - -void ft_color_mk(t_color *color, char fg[7], char bg[7]); -void ft_color_mkif(t_color *color, int cond, char fg[7], char bg[7]); - -#endif diff --git a/42sh/includes/completion.h b/42sh/includes/completion.h new file mode 100644 index 00000000..76b10e06 --- /dev/null +++ b/42sh/includes/completion.h @@ -0,0 +1,162 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* completion.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: alao +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/02/18 11:13:04 by alao #+# #+# */ +/* Updated: 2017/02/17 11:10:48 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef COMPLETION_H +# define COMPLETION_H + +# include "minishell.h" + +/* +** Autocompletion list for the valid candidates from the parser. +** id : ID of the item. +** name : Name of the item. +** type : Type of the item. +** len : Length of the name. +** cursor : Boolean to know which item is currently selected. +** next : Pointer to the next item of the list. +** prev : Pointer to the previous item of the list. +*/ + +typedef struct s_clst +{ + int id; + char *name; + int type; + int len; + int cursor; + struct s_clst *next; + struct s_clst *prev; +} t_clst; + +/* +** Autocompletion structure composed as follow: +** rcmd : The raw command from the begining to the cursor position. +** ircmd : Cursor position. +** cpath : Placeholder for the solved path. Later used for the parser. +** match : Part of the command to match when searching. +** home : Path to home for the ~ solving. +** pwd : Current folder to solve local path. +** start : See below. +** between : See below. +** trail : See below. +** cutpoint : See below. +** prompt : Size of the prompt. +** c_sx : Size of the longest word from the list. +** c_sy : Size of the list in number of item. +** c_pline : Number of item per line when printing. +** c_line : Number of line required to move to terminal up. +** win_x : Size of the window in length. +** key : The keypressed lastly. +** isfolder : If the match is a folder. boolean. +** lst : List of the item corresponding to the completion. +** +** The complete command is cutted as follow using the command as exemple: +** +** Exemple: [ ls / ; cd (tab) ; pwd ] +** +** (int)cutpoint +** | +** | +** Become: [ls / ;] [ ] [cd ] [ ; pwd] +** | | | | +** | | | | +** (char *)start (char *)between (char *)rcmd (char *)trail +*/ + +typedef struct s_comp +{ + char *rcmd; + int ircmd; + char *cpath; + char *match; + char *home; + char *pwd; + char *start; + char *between; + char *trail; + int cutpoint; + int prompt; + int c_sx; + int c_sy; + int c_pline; + int c_line; + int win_x; + int key; + int isfolder; + t_clst *lst; +} t_comp; + +/* +** Main autocompletion engine: +** completion : Main function. +** c_init : Initialization. +** c_matching : Dispatcher for binary or local files. +** c_seek_binary : Search binary using env PATH. +** c_seek_files : Solve path and search. +** c_parser : Parser. +** c_sizing : Determine the size of the column/line. +*/ + +int completion(long int key); +void c_init(t_data *s, long int input); +int c_matching(t_data *s, t_comp *c); +int c_seek_binary(t_data *s, t_comp *c); +int c_seek_files(t_data *s, t_comp *c); +int c_parser(t_comp *c, char *path, char *name); +int c_sizing(t_comp *c); + +/* +** Output functions: +** +** c_updater : Output the result to struct data. +** c_gtfo : Keypress handling. +** c_rematch : Restart on keypress. +*/ + +int c_updater(t_comp *c, char *select); +int c_gtfo(t_comp *c, long int keypress); +int c_rematch(t_comp *c, long int keypress); + +/* +** Terminal functions: +** +** c_term_mv_down : Make space for the list. +** c_term_mv_back : Reset the cursor position. +** c_term_clear : Delete the list from the terminal. +** c_printer : Printer of the list. +*/ + +void c_term_mv_down(t_comp *c); +void c_term_mv_back(t_comp *c); +void c_term_clear(t_comp *c); +void c_printer(t_comp *c); + +/* +** Support functions: +** +** c_clear : Memory clearing. +** c_clear_lst : List clearing. +** path_solver : Solve abstract path to absolute. +*/ + +int c_clear(t_data *s); +int c_clear_lst(t_comp *c); +char *path_solver(t_comp *c, char *cmd, char *cwd); + +/* +** ajout rapide gwojda pour compiler : +*/ + +int ft_sstrlen(char **s); +char *ft_sstrtostr(char **s, char *sep); + +#endif diff --git a/42sh/includes/dlst.h b/42sh/includes/dlst.h deleted file mode 100644 index 42d73729..00000000 --- a/42sh/includes/dlst.h +++ /dev/null @@ -1,35 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* dlst.h :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: jhalford +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2016/11/07 13:21:04 by jhalford #+# #+# */ -/* Updated: 2016/11/07 13:21:52 by jhalford ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#ifndef DLST_H -# define DLST_H - -struct s_dlist -{ - void *content; - size_t content_size; - struct s_dlist *next; - struct s_dlist *prev; -}; - -typedef struct s_dlist t_dlist; - -void ft_dlstadd_after(t_dlist **alst, t_dlist *new); -void ft_dlstadd_before(t_dlist **alst, t_dlist *new); -void ft_dlstdel(t_dlist **alst, void (*del)(void *, size_t)); -void ft_dlstdelone(t_dlist **alst, void (*del)(void *, size_t)); -int ft_dlstsize(t_dlist *list); -t_dlist *ft_dlstnew(void const *content, size_t content_size); -t_dlist *ft_dlstlast(t_dlist *list); -char *ft_dlsttostr(t_dlist *list); - -#endif diff --git a/42sh/includes/exec.h b/42sh/includes/exec.h index 6f6158d4..74e303ee 100644 --- a/42sh/includes/exec.h +++ b/42sh/includes/exec.h @@ -6,7 +6,7 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/11/27 20:29:56 by jhalford #+# #+# */ -/* Updated: 2017/02/06 20:41:13 by ariard ### ########.fr */ +/* Updated: 2017/02/20 20:20:15 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ @@ -33,7 +33,7 @@ # define IS_PIPESTART(a) (a & PROCESS_PIPESTART) # define IS_PIPEEND(a) (a & PROCESS_PIPEEND) -# define IS_PIPESINGLE(a) (a & (PROCESS_PIPESTART | PROCESS_PIPEEND)) +# define IS_PIPESINGLE(a) ((a & PROCESS_PIPESTART) && (a & PROCESS_PIPEEND)) # define SCRIPT_LOOP (1 << 0) @@ -49,6 +49,7 @@ struct s_process pid_t pid; int fdin; int fdout; + t_list *redirs; int toclose; int status; t_flag attributes; @@ -61,6 +62,9 @@ struct s_exec int aol_search; t_job job; t_process process; + int fd0save; + int fd1save; + int fd2save; }; struct s_execmap @@ -69,9 +73,16 @@ struct s_execmap int (*f)(t_btree **ast); }; +struct s_redirmap +{ + t_flag type; + int (*f)(t_redir *redir); +}; + #include "minishell.h" extern t_execmap g_execmap[]; +extern t_redirmap g_redirmap[]; int ft_exec(t_btree **ast); @@ -82,10 +93,7 @@ int exec_ampersand(t_btree **ast); int exec_or_if(t_btree **ast); int exec_and_if(t_btree **ast); int exec_pipe(t_btree **ast); - -int exec_less(t_btree **ast); -int exec_great(t_btree **ast); -int exec_dgreat(t_btree **ast); +int exec_redir(t_btree **ast); int exec_command(t_btree **ast); int exec_while(t_btree **ast); @@ -99,13 +107,20 @@ int exec_default(t_btree **ast); int launch_process(t_process *p); int process_setexec(t_type type, t_process *p); int process_setgroup(t_process *p, pid_t pid); -int process_redirect(t_process *p); void process_setsig(void); void process_free(void *content, size_t content_size); -void process_reset(void); +void process_reset(t_process *p); +void process_resetfds(void); -void fd_redirect(void); -void fd_reset(void); +int fd_is_valid(int fd); +int bad_fd(int fd); +int process_redirect(t_process *p); +int redirect_great(t_redir *redir); +int redirect_less(t_redir *redir); +int redirect_dgreat(t_redir *redir); +int redirect_dless(t_redir *redir); +int redirect_greatand(t_redir *redir); +int redirect_lessand(t_redir *redir); char *ft_findexec(char *path, char *file); diff --git a/42sh/includes/ft_printf.h b/42sh/includes/ft_printf.h deleted file mode 100644 index 6db739f4..00000000 --- a/42sh/includes/ft_printf.h +++ /dev/null @@ -1,81 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* ftprintf.h :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: jhalford +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2016/11/07 13:22:54 by jhalford #+# #+# */ -/* Updated: 2016/12/15 15:29:22 by jhalford ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#ifndef FT_PRINTF_H -# define FT_PRINTF_H -# include "libft.h" -# include -# define ALL_FLAGS "#0- +" -# define ALL_CONVERSIONS "sSpdDioOuUxXcCb" - -typedef struct s_fmt t_fmt; -typedef struct s_conv t_conv; -typedef char *(t_converter)(t_fmt *fmt, va_list ap); -typedef void (t_pad_func)(char *str, t_fmt *fmt); - -struct s_conv -{ - char id; - char allowed_flags[6]; - char base[20]; - t_converter *converter; - t_pad_func *sharp_func; -}; - -struct s_fmt -{ - char flags[6]; - int width; - int precision; - char modifier[3]; - char conversion; - int valid; - t_conv conv; -}; - -int ft_vdprintf(int fd, const char *format, va_list ap); -int ft_fmtcalc(char **final, char **str, va_list ap); - -extern t_conv g_convs[]; - -t_fmt *ft_fmt_init(void); -void ft_fmt_print(t_fmt *fmt); -void ft_printf_color(int fd, char **final, char **str); - -t_fmt *ft_printf_parse(char **format, va_list ap); -void ft_printf_parse_flags(t_fmt *fmt, char **format); -void ft_printf_parse_width(t_fmt *fmt, char **format, va_list ap); -void ft_printf_parse_precision(t_fmt *fmt, char **format, va_list ap); -void ft_printf_parse_modifiers(t_fmt *fmt, char **format); - -char *ft_transform(t_fmt *fmt, va_list ap); - -void ft_fmt_error_conv(char conv); -void ft_fmt_error_mod_conv(char *mod, char conv); -void ft_fmt_error_flag_conv(char flag, char conv); -void ft_fmt_error_flag_flag(char flag1, char flag2); - -void ft_fmt_simplify(t_fmt *fmt); -int ft_fmt_validate_conv(t_fmt *fmt); -void ft_fmt_validate_flags(t_fmt *fmt); -void ft_fmt_validate_mod(t_fmt *fmt); - -char *ft_signed_conversion(t_fmt *fmt, va_list ap); -char *ft_unsigned_conversion(t_fmt *fmt, va_list ap); -char *ft_str_conversion(t_fmt *fmt, va_list ap); -char *ft_char_conversion(t_fmt *fmt, va_list ap); - -void ft_pad_sharp_o(char *str, t_fmt *fmt); -void ft_pad_sharp_xb(char *str, t_fmt *fmt); -void ft_pad_left(char *str, t_fmt *fmt); -void ft_pad_right(char *str, t_fmt *fmt); -#endif diff --git a/42sh/includes/ft_readline.h b/42sh/includes/ft_readline.h index 1c7cd31b..2522979b 100644 --- a/42sh/includes/ft_readline.h +++ b/42sh/includes/ft_readline.h @@ -6,7 +6,7 @@ /* By: gwojda +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2017/01/23 10:35:44 by gwojda #+# #+# */ -/* Updated: 2017/02/03 15:25:40 by ariard ### ########.fr */ +/* Updated: 2017/02/20 20:21:45 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ @@ -54,6 +54,30 @@ # define TOUCHE_F5 892427035 # define TOUCHE_F6 925981467 +/* # define PROMPT_QUOTES "quote> " */ +/* # define PROMPT_DQUOTES "dquote> " */ +/* # define PROMPT_BQUOTES "bquote> " */ +/* # define PROMPT_ACCOLADE "cursh> " */ +/* # define PROMPT_BRACKET "subsh> " */ +/* # define PROMPT_BSLASH "> " */ + +/* # define SIZE_PROMPT_QUOTES 7 */ +/* # define SIZE_PROMPT_DQUOTES 8 */ +/* # define SIZE_PROMPT_BQUOTES 8 */ +/* # define SIZE_PROMPT_ACCOLADE 7 */ +/* # define SIZE_PROMPT_BRACKET 7 */ +/* # define SIZE_PROMPT_BSLASH 2 */ + +# define IS_QUOTES (1 << 0) +# define IS_BQUOTES (1 << 1) +# define IS_DQUOTES (1 << 2) +# define IS_BSLASH (1 << 3) +# define IS_ACCOLADE (1 << 4) +# define IS_BRACKET (1 << 5) + +# define STR data_singleton()->line.input +# define POS data_singleton()->line.pos + # define HIST 1 # define ERROR_CNTL_R 1 @@ -84,9 +108,24 @@ typedef struct s_key void (*f)(void); } t_key; -extern t_key g_keys[]; +typedef struct s_prompt_type +{ + char key; + int value; + char *new_prompt; +} t_prompt_type; +typedef struct s_brackets +{ + int pos; + char tabl[100]; +} t_brackets; +extern t_key g_keys[]; +extern t_prompt_type g_prompt_tab[]; +extern t_brackets g_brackets; + +void ft_reset_tab(char *tabl); void ft_putnc(char c, int n); int ft_nbr_len(int nbr); void ft_puttermcaps(char *str); @@ -111,10 +150,10 @@ void ft_realloc_str_history(char **str, size_t pos, int nb_his, int len); void ft_realloc_str_history_2(char **str, size_t pos, char *s); long long ft_pow(int nbr, int power); void ft_realloc_str_history_3(char **str, size_t pos, char *s); -void ft_check_backslash(char **str); char *ft_strget_history(char *str); int ft_nb_last_line(char *str, size_t pos); int ft_put(int nb); +void ft_check_line(void); char *ft_read_stdin(void); void ft_end(void); @@ -138,12 +177,16 @@ void ft_found_prev_word(void); void ft_c(void); void ft_x(void); void ft_v(void); -void ft_history_parsing(void); void ft_read_it(int input, size_t *pos, char **str); -int ft_readline(void); +char *readline(char *); +int ft_completion(int ret); -void ft_check_heredoc(char **str); -void ft_check_quotes(char **s); +struct termios *ft_save_termios(int save); +char *ft_strdupi_w(char const *s); + +void ft_add_str_in_history(char *str); +void ft_init_history(void); +char *ft_history_parsing(void); #endif diff --git a/42sh/includes/glob.h b/42sh/includes/glob.h index 96cf40f2..33019718 100644 --- a/42sh/includes/glob.h +++ b/42sh/includes/glob.h @@ -6,7 +6,7 @@ /* By: wescande +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2017/01/04 16:31:18 by wescande #+# #+# */ -/* Updated: 2017/02/01 19:50:07 by wescande ### ########.fr */ +/* Updated: 2017/02/20 19:03:45 by wescande ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,6 +17,8 @@ # define CH(x) ((char **)(x)->content) # define UCH(x) ((unsigned char **)(x)->content) +# define SCH(x) ((char **)(x).content) +# define SUCH(x) ((unsigned char **)(x).content) typedef struct s_ld { @@ -27,8 +29,11 @@ typedef struct s_ld typedef struct s_glob { - const char *pat; - const unsigned char *esc; + short int found; + short int cur_dir; + char *pat; + unsigned char *esc; + unsigned char *esc2; t_ld *match; t_ld *m_pat; } t_glob; @@ -43,33 +48,58 @@ typedef struct s_expand char *s1; } t_expand; +typedef struct s_bquote +{ + t_ld **wk; + char *str; + unsigned char *esc; + unsigned char *esc2; + char *s1; + char *s2; + char *mid; +} t_bquote; /* ** interface of glob. */ -char **glob(const char *str, const unsigned char *esc); +char **glob(char *str, unsigned char *esc, + unsigned char *dbl_esc); +void esc_print(char *str, unsigned char *esc); /* ** return TRUE if path file is a directory. */ int is_directory(const char *path); + /* ** return TRUE if char at str_pos in ini_str is escape. +** five the possibility to set if the char is esc or not. */ int is_char_esc(const unsigned char *esc, const char *ini_str, const char *str_pos); +void set_char_esc_mode(unsigned char *esc, + const char *ini_str, const char *str_pos, int mode); +void set_char_esc(unsigned char *esc, + const char *ini_str, const char *str_pos); +void set_char_no_esc(unsigned char *esc, + const char *ini_str, const char *str_pos); /* ** Internal function. */ unsigned char *ft_sub_esc(const unsigned char *esc, int start, int len); +unsigned char *dup_char_esc(const unsigned char *esc, const int size); unsigned char *calc_expand_esc(const unsigned char *esc, - int nb_start, int nb_middle, int *nb_end); + int nb_start, int *nb_middle, int *nb_end); void modify_esc_split(unsigned char *esc_dest, unsigned char *esc_src, int start, int len); void expand_brace(t_glob *tglob); +void expand_bquote(t_glob *gl); +void expand_var(t_glob *tglob); int match_pattern(t_glob *tglob, char *str, char *full_word); -int dir_research(t_glob *tglob, char *p, const char *pat, int rec); +int dir_research(t_glob *tglob, char *p, char *pat, int rec); +char **gen_tab(const char *pat, const unsigned char *esc, + const unsigned char *esc2, int dup); char **ft_strsplit_spe(const char *str, const unsigned char *esc, char c); unsigned char **ft_strsplit_esc(const char *str, @@ -95,7 +125,10 @@ t_ld *ft_ld_order(t_ld *ld, int (*f)(), void (*del)()); */ char *ft_strjoinf(char *str, char *str2, int mode); +char *ft_strsubf(char *s, unsigned int start, + size_t len, short int mode); void ft_tabdel(char ***mytab); int ft_tablen(char **mytab); +void *ft_memrealloc(void *ptr, size_t old_s, size_t new_s); #endif diff --git a/42sh/includes/hash.h b/42sh/includes/hash.h new file mode 100644 index 00000000..ebdde0b7 --- /dev/null +++ b/42sh/includes/hash.h @@ -0,0 +1,34 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* hash.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/18 11:10:14 by gwojda #+# #+# */ +/* Updated: 2017/02/19 10:59:19 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef HASH_H +# define HASH_H + +# define MAX_HASH 200 + +extern t_list *g_hash[MAX_HASH]; + +typedef struct s_hash +{ + char *key; + char *path; +} t_hash; + +int ft_add_hash(t_process *p); +int ft_hash(t_process *p); +int ft_is_hash(t_process *p); +int ft_hash_str(char *str); + +void ft_hash_free(void *ptr, size_t size); +void ft_free_hash_table(void); + +#endif diff --git a/42sh/includes/lexer.h b/42sh/includes/lexer.h index 705bef68..348bf334 100644 --- a/42sh/includes/lexer.h +++ b/42sh/includes/lexer.h @@ -6,7 +6,7 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/12/01 12:15:50 by jhalford #+# #+# */ -/* Updated: 2017/02/15 19:46:49 by ariard ### ########.fr */ +/* Updated: 2017/02/20 20:20:07 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,67 +14,13 @@ # define LEXER_H # include "minishell.h" +# include "libft.h" +# include "types.h" -typedef long long t_type; - -/* - * Token need : - * DLESSDASH - * CLOBBER - * LESSGREAT - * IO_NUMBER - * NAME - * DSEMI - * ASSIGNEMENT_WORD - * Lbrace - * Rbrace - * Bang - * Case - * Esac - * for - * in - * -*/ - - -/* -# define TK_LESS (1 << 0) //transparent -# define TK_GREAT (1 << 1) //transparent -# define TK_DLESS (1 << 2) -# define TK_DGREAT (1 << 3) -# define TK_LESSAND (1 << 4) -# define TK_GREATAND (1 << 5) -# define TK_SEMI (1 << 6) -# define TK_PIPE (1 << 7) -# define TK_AND_IF (1 << 8) -# define TK_OR_IF (1 << 9) -# define TK_AMP (1 << 10) -# define TK_PAREN_OPEN (1 << 11) -# define TK_PAREN_CLOSE (1 << 12) -# define TK_BQUOTE (1 << 13) -# define TK_N_WORD (1 << 14) -# define TK_Q_WORD (1 << 15) -# define TK_DQ_WORD (1 << 16) -# define TK_COMMAND (1 << 17) -# define TK_SUBSHELL (1 << 18) -# define TK_NEWLINE (1 << 19) -# define TK_WHILE (1 << 20) -# define TK_DO (1 << 21) -# define TK_DONE (1 << 22) -# define TK_IF (1 << 23) -# define TK_THEN (1 << 24) -# define TK_FI (1 << 25) -# define TK_ELIF (1 << 26) -# define TK_ELSE (1 << 27) -# define TK_UNTIL (1 << 28) -*/ - -# define TK_WORD (TK_N_WORD | TK_Q_WORD | TK_DQ_WORD) -# define TK_REDIR (0x1 | 0x2 | 0x4 | 0x8 | 0x10 | 0x20) +//# define TK_REDIR (0x1 | 0x2 | 0x4 | 0x8 | 0x10 | 0x20) # define TK_NON_FREEABLE (TK_PAREN_OPEN | TK_PAREN_CLOSE | TK_BQUOTE) # define RW_SEP (TK_NEWLINE | TK_AMP | TK_SEMI | TK_WHILE | TK_DONE\ | TK_DO | TK_IF | TK_FI | TK_THEN | TK_ELIF | TK_ELSE) - enum e_lexstate { DEFAULT, @@ -83,12 +29,15 @@ enum e_lexstate SEP, WORD, NUMBER, - GREAT, LESS, - GREATAND, + GREAT, LESSAND, + GREATAND, + DLESS, QUOTE, DQUOTE, + BQUOTE, + DQUOTE_BQUOTE, BACKSLASH, VAR, SPECIAL, @@ -99,6 +48,9 @@ enum e_lexstate THEN, FI, COMMENT, + PAREN, + COMMENT, + END, }; struct s_token @@ -106,28 +58,37 @@ struct s_token t_type type; char *data; unsigned char *esc; + unsigned char *esc2; int size; }; -typedef struct s_data t_data; -typedef struct s_token t_token; -typedef enum e_lexstate t_lexstate; +struct s_lexer +{ + char *str; + int pos; + t_lexstate state; + t_list *stack; + t_list *heredoc_stack; +}; -extern int (*g_lexer[])(t_list **alst, char *str); -int ft_lexer(t_list **alst, char **str); -int ft_tokenize(t_list **alst, char *str, t_lexstate state); +extern int (*g_lexer[])(t_list **alst, t_lexer *lexer); + int ft_post_tokenize(t_list **alst, char **str); t_token *token_init(); -int token_append(t_token *token, char c, short int esc); +int token_append(t_token *token, t_lexer *lexer, + short int esc, short int esc2); +int token_append_char(t_token *token, char c, + short int esc, short int esc2); +int token_append_str(t_token *token, char *str, + short int esc, short int esc2); void token_free(void *data, size_t size); int token_cmp_type(t_token *token, t_type *ref); void token_print(t_list *lst); -void token_expand_var(t_token *token); int reduce_parens(t_list **alst, char *str); -int reduce_bquotes(t_list **alst, char **str); +int bquotes_expand(t_list **alst); char *command_getoutput(char *command); int ft_is_delim(char c); @@ -158,5 +119,32 @@ int lexer_then(t_list **alst, char *str); int lexer_fi(t_list **alst, char *str); int lexer_list(t_list **alst, char *str); int lexer_comment(t_list **alst, char *str); +======= +char *stack_to_prompt(t_list *stack); + +t_lexstate get_state_global(t_lexer *lexer); +t_lexstate get_state_redir(t_lexer *lexer); +int get_lexer_stack(t_lexer lexer); +void lexer_init(t_lexer *lexer); +int lexer_lex(t_list **alst, t_lexer *lexer); +int lexer_default(t_list **alst, t_lexer *lexer); +int lexer_newline(t_list **alst, t_lexer *lexer); +int lexer_delim(t_list **alst, t_lexer *lexer); +int lexer_sep(t_list **alst, t_lexer *lexer); +int lexer_word(t_list **alst, t_lexer *lexer); +int lexer_number(t_list **alst, t_lexer *lexer); +int lexer_less(t_list **alst, t_lexer *lexer); +int lexer_great(t_list **alst, t_lexer *lexer); +int lexer_greatand(t_list **alst, t_lexer *lexer); +int lexer_lessand(t_list **alst, t_lexer *lexer); +int lexer_dless(t_list **alst, t_lexer *lexer); +int lexer_quote(t_list **alst, t_lexer *lexer); +int lexer_dquote(t_list **alst, t_lexer *lexer); +int lexer_bquote(t_list **alst, t_lexer *lexer); +int lexer_backslash(t_list **alst, t_lexer *lexer); +int lexer_paren(t_list **alst, t_lexer *lexer); +int lexer_comment(t_list **alst, t_lexer *lexer); +int lexer_end(t_list **alst, t_lexer *lexer); +>>>>>>> master #endif diff --git a/42sh/includes/libft.h b/42sh/includes/libft.h deleted file mode 100644 index ecbe6bb5..00000000 --- a/42sh/includes/libft.h +++ /dev/null @@ -1,162 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* libft.h :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: jhalford +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2016/11/07 13:49:04 by jhalford #+# #+# */ -/* Updated: 2017/01/19 16:13:05 by gwojda ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#ifndef LIBFT_H -# define LIBFT_H - -# define STDIN 0 -# define STDOUT 1 -# define STDERR 2 -# define STDBUG 3 - -# define DG_MSG0 "{inv}{yel}%21s {bol}{blu}%-3d{eoc}" -# define DG_MSG1 ft_path_notdir(__FILE__), __LINE__ -# define DG(f, ...) ft_dprintf(STDBUG, DG_MSG0 f "{eoc}\n", DG_MSG1, ##__VA_ARGS__) - -# include "get_next_line.h" -# include "ft_xattr.h" -# include "mytime.h" -# include "lst.h" -# include "dlst.h" -# include "btree.h" -# include "color.h" - -# include -# include -# include -# include -# include -# include -# include - -# define FT_WS(x) (x == ' ' || x == '\t' || x == '\n') -# define FT_ABS(x) (((x) < 0) ? -(x) : (x)) -# define FT_NEG(x) (((x) < 0) ? 1 : 0) -# define FT_POS(x) (((x) > 0) ? 1 : 0) -# define FT_MIN(a, b) ((a) < (b) ? (a) : (b)) -# define FT_MAX(a, b) ((a) > (b) ? (a) : (b)) -# define FT_DIST(a, b) (FT_ABS((a) - (b))) - -typedef struct s_stof t_stof; -typedef struct s_stos t_stos; - -struct s_stos -{ - char *key; - char *val; -}; - -struct s_stof -{ - char *name; - int (*f)(); -}; - -void ft_debug(void); - -void *ft_memset(void *b, int c, size_t len); -void ft_bzero(void *s, size_t n); -void *ft_memcpy(void *dst, const void *src, size_t n); -void *ft_memccpy(void *dst, const void *src, int c, size_t n); -void *ft_memmove(void *dst, const void *src, size_t len); -void *ft_memchr(const void *s, int c, size_t n); -int ft_memcmp(const void *s1, const void *s2, size_t n); -size_t ft_strlen(const char *s); -char *ft_strdup(const char *s1); -char *ft_strcpy(char *dst, const char *src); -char *ft_strncpy(char *dst, const char *src, size_t len); -char *ft_strcat(char *s1, const char *s2); -char *ft_strncat(char *s1, const char *s2, size_t n); -size_t ft_strlcat(char *dst, const char *src, size_t size); -char *ft_strchr(const char *s, int c); -char *ft_strrchr(const char *s, int c); -char *ft_strstr(const char *big, const char *little); -char *ft_strnstr(const char *big, const char *little, size_t len); -int ft_strcmp(const char *s1, const char *s2); -int ft_strncmp(const char *s1, const char *s2, size_t n); -int ft_atoi(const char *str); -int ft_isalpha(int c); -int ft_isdigit(int c); -int ft_isalnum(int c); -int ft_isascii(int c); -int ft_isprint(int c); -int ft_toupper(int c); -int ft_tolower(int c); - -void *ft_memalloc(size_t size); -void ft_memdel(void **ap); -char *ft_strnew(size_t size); -void ft_strdel(char **as); -void ft_strclr(char *s); -void ft_striter(char *s, void (*f)(char *)); -void ft_striteri(char *s, void (*f)(unsigned int, char *)); -char *ft_strmap(char const *s, char (*f)(char)); -char *ft_strmapi(char const *s, char (*f)(unsigned int, char)); -int ft_strequ(char const *s1, char const *s2); -int ft_strnequ(char const *s1, char const *s2, size_t n); -char *ft_strsub(char const *s, unsigned int start, size_t len); -char *ft_strjoin(char const *s1, char const *s2); -char *ft_strtrim(char const *s); -char **ft_strsplit(char const *s, char c); -char *ft_itoa(int n); -int ft_putchar(int c); -void ft_putstr(char const *s); -void ft_putendl(char const *s); -void ft_putnbr(int n); -void ft_putchar_fd(char c, int fd); -void ft_putstr_fd(char const *s, int fd); -void ft_putendl_fd(char const *s, int fd); -void ft_putnbr_fd(int n, int fd); -void ft_putaddr(void *a); - -char *ft_strrev(char *str); -char **ft_strsplit(char const *s, char c); -char *ft_str3join(char const *s1, char const *s2, char const *s3); -char *ft_strcut(char *str, char *cut); -char **ft_split_whitespaces(char const *str); -char *ft_convert_base( - char *str, char *base_from, char *base_to, char *flags); -char *ft_strcatf(char *s1, const char *s2); -char *ft_strinsert(char *str, char c, int n); -int ft_strappend(char **dst, char *src); -char *ft_strbetween(char *start, char *end); -char *ft_strreplace(char **str, char *start, char *end, char *new); - -char *ft_itoa_base(int nbr, char *base, char *flags); -char *ft_lltoa_base(long long nbr, char *base, char *flags); -char *ft_ulltoa_base(unsigned long long nbr, char *base); -char *ft_uitoa_base(unsigned int nbr, char *base); -size_t ft_ilen(int n); -size_t ft_ilen_base(int n, int base); -size_t ft_uilen(unsigned int n); -size_t ft_lllen(long long n); -size_t ft_lllen_base(long long n, int base); -int ft_addrcmp(void *a, void *b); - -char **ft_sstradd(char **list, char *new); -void ft_sstrsort(char **list, int (*cmp)()); -void ft_sstrprint(char **list, char sep); -void ft_sstrprint_fd(int fd, char **list, char sep); -char **ft_sstrdup(char **list); -void ft_sstrdel(char **sstr, int index); -void ft_sstrfree(char **sstr); -char *ft_sstrcat(char **sstr, char sep); - -char *ft_path_notdir(char *path); - -int ft_printf(const char *format, ...); -int ft_dprintf(int fd, const char *format, ...); - -char *ft_getenv(char **env, char *key); - -void *ft_realloc(void *data, int size); -#endif diff --git a/42sh/includes/line_editing.h b/42sh/includes/line_editing.h deleted file mode 100644 index 13c408ec..00000000 --- a/42sh/includes/line_editing.h +++ /dev/null @@ -1,89 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* line-editing.h :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: jhalford +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2016/11/10 13:38:21 by jhalford #+# #+# */ -/* Updated: 2017/01/23 21:45:02 by ariard ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#ifndef LINE_EDITING_H -# define LINE_EDITING_H - -# include "minishell.h" -# include -# include - -# define SHELL_PROMPT "$> " -# define BUFF_SIZE 32 -# define READ_BUF 32 -# define FT_KEY_C_C "\x3" -# define FT_KEY_C_D "\x4" -# define FT_KEY_C_H "\x8" -# define FT_KEY_TAB "\x9" -# define FT_KEY_ENTER "\xa" -# define FT_KEY_C_K "\xb" -# define FT_KEY_C_L "\xc" -# define FT_KEY_C_U "\x15" -# define FT_KEY_C_Z "\x1a" -# define FT_KEY_ESC "\x1b" -# define FT_KEY_UP "\x1b\x5b\x41" -# define FT_KEY_DOWN "\x1b\x5b\x42" -# define FT_KEY_RIGHT "\x1b\x5b\x43" -# define FT_KEY_LEFT "\x1b\x5b\x44" -# define FT_KEY_C_UP "\x1b\x4f\x41" -# define FT_KEY_C_DOWN "\x1b\x4f\x42" -# define FT_KEY_C_RIGHT "\x1b\x4f\x43" -# define FT_KEY_C_LEFT "\x1b\x4f\x44" -# define FT_KEY_SQUOTE "\x22" -# define FT_KEY_DQUOTE "\x27" -# define FT_KEY_BSLASH "\x5c" -# define FT_KEY_DEL "\x7f" - -enum e_qstate -{ - Q_NONE, - Q_QUOTE, - Q_DQUOTE, - Q_BACKSLASH, -}; - -typedef struct s_data t_data; -typedef enum e_qstate t_qstate; - -extern t_stof g_keys[]; - -int ft_interactive_sh(t_data *data); -int input_init(t_data *data); -int ft_set_termios(t_data *data, int input_mode); -int ft_prompt(void); - -int ft_history_add(t_data *data); - -int ft_clear_line(t_data *data, char *buf); -int ft_line_up(t_data *data, char *buf); -int ft_line_down(t_data *data, char *buf); -int ft_line_start(t_data *data, char *buf); -int ft_line_end(t_data *data, char *buf); - -int ft_key_del(t_data *data, char *buf); -int ft_key_enter(t_data *data, char *buf); -int ft_key_ctrl_d(t_data *data, char *buf); -int ft_key_ctrl_c(t_data *data, char *buf); -int ft_key_default(t_data *data, char *buf); - -int ft_history_up(t_data *data, char *buf); -int ft_history_down(t_data *data, char *buf); -int ft_cursor_left(t_data *data, char *buf); -int ft_cursor_right(t_data *data, char *buf); -int ft_word_left(t_data *data, char *buf); -int ft_word_right(t_data *data, char *buf); - -void qstate_none(t_qstate *new, char c); -void qstate_quote(t_qstate *new, char c); -void qstate_dquote(t_qstate *new, char c); - -#endif diff --git a/42sh/includes/lst.h b/42sh/includes/lst.h deleted file mode 100644 index ee4926df..00000000 --- a/42sh/includes/lst.h +++ /dev/null @@ -1,80 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* lst.h :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: jhalford +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2016/11/07 13:27:46 by jhalford #+# #+# */ -/* Updated: 2016/12/12 14:59:12 by jhalford ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#ifndef LST_H -# define LST_H - -# include "libft.h" - -struct s_list -{ - void *content; - size_t content_size; - struct s_list *next; -}; - -typedef struct s_list t_list; - -t_list *ft_lstnew(void const *content, size_t content_size); -void ft_lstdel(t_list **alst, void (*del)(void *, size_t)); -void ft_lstdelone(t_list **alst, void (*del)(void *, size_t)); -void ft_lstadd(t_list **alst, t_list *new); -void ft_lstiter(t_list *lst, void (*f)(t_list *elem)); -t_list *ft_lstmap(t_list *lst, t_list *(*f)(t_list *elem)); - -t_list *ft_lstnew_range(int a, int b); -void ft_lsteadd(t_list **alst, t_list *new); -void ft_lstnadd(t_list **alst, t_list *new, int n); -void ft_lstsort(t_list **begin_list, int (*cmp)()); -void ft_lst_print(t_list *list, void (*printer)()); -int ft_lstsize(t_list *lst); -t_list *ft_lstlast(t_list *lst); -void ft_lst_sorted_merge( - t_list **begin_list1, - t_list *begin_list2, - int (*cmp)()); -void ft_lst_sorted_insert( - t_list **begin_list, - t_list *insert, - int (*cmp)()); -void ft_lst_delif( - t_list **alist, - void *data_ref, - int (*cmp)(), - void (*del)(void *, size_t)); -void ft_lst_delsub( - t_list **alst, - t_list *sub, int (*cmp)(), - void (*del)(void *, size_t)); -void ft_lst_cfree(void *ptr, size_t size); -void ft_lst_bfree(void *ptr, size_t size); -t_list *ft_lst_filter( - t_list *lst, - void const *data_ref, - t_list *(*f)(t_list *elem, void const *)); -t_list *ft_lst_removeif( - t_list **alst, - void *data_ref, - int (*cmp)()); -t_list *ft_lst_find( - t_list *begin_list, - void *data_ref, - int (*cmp)()); -t_list *ft_lstpop(t_list **lst); -void ft_lst_merge(t_list **begin_list1, t_list *begin_list2); -void ft_lst_reverse(t_list **begin_list); - -int ft_diff(void *a, void *b); -t_list *ft_id(t_list *a); -t_list *ft_lst_at(t_list *list, unsigned int nbr); - -#endif diff --git a/42sh/includes/minishell.h b/42sh/includes/minishell.h index f1870080..c3368eed 100644 --- a/42sh/includes/minishell.h +++ b/42sh/includes/minishell.h @@ -6,7 +6,7 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/11/10 13:07:44 by jhalford #+# #+# */ -/* Updated: 2017/02/15 19:22:59 by ariard ### ########.fr */ +/* Updated: 2017/02/20 20:23:20 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,7 +15,6 @@ # define SHELL_NAME "minishell" # include "libft.h" - # include "types.h" # include "lexer.h" # include "parser.h" @@ -24,6 +23,8 @@ # include "builtin.h" # include "job_control.h" # include "glob.h" +# include "completion.h" +# include "hash.h" # include # include @@ -32,21 +33,17 @@ # include # include -struct s_comp -{ - int a; -}; +# define SH_INTERACTIVE (1 << 0) +# define SH_OPTS_JOBC (1 << 1) +# define SH_OPTS_LC (1 << 2) +# define SH_MODE_INPUT (1 << 3) +# define SH_MODE_EXEC (1 << 4) -# define SHELL_OPTS_JOBC (1 << 0) -# define SHELL_OPTS_LC (1 << 1) -# define SHELL_MODE_INPUT (1 << 2) -# define SHELL_MODE_EXEC (1 << 3) -# define SHELL_MODE_SCRIPT (1 << 4) +# define SH_MODE_MASK (SH_MODE_INPUT | SH_MODE_EXEC) +# define SH_HAS_JOBC(b) (b & SH_OPTS_JOBC) +# define SH_IS_INTERACTIVE(b) (b & SH_INTERACTIVE) -# define SHELL_MODE_MASK (SHELL_MODE_INPUT | SHELL_MODE_EXEC | SHELL_MODE_SCRIPT) -# define SHELL_HAS_JOBC(b) (b & SHELL_OPTS_JOBC) - -# define SHELL_MSG_NOJOBC "no job-control" +# define SH_MSG_NOJOBC "no job-control" struct s_script { @@ -65,7 +62,7 @@ struct s_data char **argv; t_flag opts; t_line line; - t_comp comp; + t_comp *comp; t_exec exec; t_jobc jobc; t_script script; @@ -80,17 +77,7 @@ void shell_exit(void); int data_init(void); void data_exit(void); -int shell_single_command(char *command); - -int read_script(char *file); -int shell_script(void); -int get_script_content(t_script *script); - -void ft_expand_dollar(char **av, char **env); -char *ft_findexec(char *path, char *file); - char *ft_putast(void *node); void ft_putast2(void *node); -void ft_print_all_ast(t_list *lst_ast); #endif diff --git a/42sh/includes/parser.h b/42sh/includes/parser.h index 30b55db3..3cfa52c8 100644 --- a/42sh/includes/parser.h +++ b/42sh/includes/parser.h @@ -6,7 +6,7 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/12/01 12:15:54 by jhalford #+# #+# */ -/* Updated: 2017/02/20 17:07:02 by ariard ### ########.fr */ +/* Updated: 2017/02/20 20:26:50 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ @@ -239,13 +239,6 @@ typedef union u_astdata t_astdata; typedef union u_word t_word; typedef long long t_type; -struct s_parser -{ - t_type type; - int (*f)(t_btree **ast, - t_list **start, t_list **token); -}; - union u_word { char *word; @@ -254,9 +247,10 @@ union u_word struct s_redir { + t_flag type; int n; - int close; t_word word; + int close; }; union u_astdata @@ -285,6 +279,7 @@ int get_sub_instruction(t_btree **ast, t_list **start, t_list **lst); int parse_newline(t_btree **ast, t_list **start, t_list **lst); int parse_separator(t_btree **ast, t_list **start, t_list **lst); +int parse_redir(t_btree **ast, t_list **start, t_list **lst); int parse_less(t_btree **ast, t_list **start, t_list **lst); int parse_great(t_btree **ast, t_list **start, t_list **lst); int parse_dless(t_btree **ast, t_list **start, t_list **lst); diff --git a/42sh/includes/types.h b/42sh/includes/types.h index 7f87c28a..f2175ab8 100644 --- a/42sh/includes/types.h +++ b/42sh/includes/types.h @@ -6,29 +6,38 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/12/13 17:11:48 by jhalford #+# #+# */ -/* Updated: 2017/01/30 18:11:14 by ariard ### ########.fr */ +/* Updated: 2017/02/20 21:03:25 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ #ifndef TYPES_H # define TYPES_H -typedef long long t_type; -typedef struct s_line t_line; -typedef struct s_comp t_comp; -typedef struct s_exec t_exec; -typedef struct s_jobc t_jobc; -typedef enum e_mode t_mode; +typedef struct s_data t_data; -typedef struct s_data t_data; -typedef enum e_qstate t_qstate; - -typedef struct s_job t_job; -typedef struct s_jobc t_jobc; -typedef struct s_execmap t_execmap; -typedef struct s_process t_process; typedef long long t_type; typedef long long t_flag; +typedef struct s_line t_line; +typedef struct s_comp t_comp; +typedef struct s_exec t_exec; +typedef struct s_jobc t_jobc; +typedef enum e_mode t_mode; + +typedef struct s_lexer t_lexer; +typedef enum e_lexstate t_lexstate; +typedef struct s_token t_token; + +typedef struct s_parser t_parser; +typedef struct s_ld t_ld; +typedef struct s_astnode t_astnode; +typedef struct s_redir t_redir; +typedef union u_astdata t_astdata; +typedef union u_word t_word; + +typedef struct s_job t_job; +typedef struct s_execmap t_execmap; +typedef struct s_redirmap t_redirmap; +typedef struct s_process t_process; typedef int (t_execf)(const char *path, char *const argv[], char *const envp[]); t_data *data_singleton(); diff --git a/42sh/libft b/42sh/libft index ab92f0e5..9aa3049d 160000 --- a/42sh/libft +++ b/42sh/libft @@ -1 +1 @@ -Subproject commit ab92f0e5d817c9d726a8ccf2f11c084ba446bbdf +Subproject commit 9aa3049dd23424807316a6f027589a95cdf1fcdd diff --git a/42sh/src/builtin/bt_read_get.c b/42sh/src/builtin/bt_read_get.c index a7364b71..62700b5a 100644 --- a/42sh/src/builtin/bt_read_get.c +++ b/42sh/src/builtin/bt_read_get.c @@ -6,7 +6,7 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2017/01/21 18:00:03 by jhalford #+# #+# */ -/* Updated: 2017/01/22 16:24:55 by jhalford ### ########.fr */ +/* Updated: 2017/02/03 15:58:41 by jhalford ### ########.fr */ /* */ /* ************************************************************************** */ diff --git a/42sh/src/builtin/bt_read_term.c b/42sh/src/builtin/bt_read_term.c index 853929c4..131eaaf7 100644 --- a/42sh/src/builtin/bt_read_term.c +++ b/42sh/src/builtin/bt_read_term.c @@ -6,7 +6,7 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2017/01/25 16:02:05 by jhalford #+# #+# */ -/* Updated: 2017/01/27 19:00:10 by jhalford ### ########.fr */ +/* Updated: 2017/02/06 13:56:47 by jhalford ### ########.fr */ /* */ /* ************************************************************************** */ @@ -27,7 +27,9 @@ int bt_read_terminit(t_read *data) (void)data; term = bt_read_term(1); - term.c_lflag &= ~(ECHO | ICANON); + term.c_lflag &= ~(ICANON); + if (data->opts & READ_OPT_LS) + term.c_lflag &= ~(ECHO); if (data->opts & READ_OPT_LT) { term.c_cc[VTIME] = data->timeout * 10; diff --git a/42sh/src/builtin/builtin_cd.c b/42sh/src/builtin/builtin_cd.c index 7be11cca..c7924678 100644 --- a/42sh/src/builtin/builtin_cd.c +++ b/42sh/src/builtin/builtin_cd.c @@ -3,20 +3,20 @@ /* ::: :::::::: */ /* builtin_cd.c :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: jhalford +#+ +:+ +#+ */ +/* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/12/03 11:57:53 by jhalford #+# #+# */ -/* Updated: 2017/01/27 15:12:12 by ariard ### ########.fr */ +/* Updated: 2017/02/20 20:29:26 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ #include "builtin.h" #define CDOPT_L (1 << 0) -#define CDOPT_P (1 << 2) +#define CDOPT_P (1 << 1) #define HAS_CDOPT_P(x) (x & CD_OPT_P) #define HAS_CDOPT_L(x) (x & CD_OPT_L) -#define CDERR_1 "cd: no such file or directory: %s\n" +#define CDERR_1 "{red}cd: no such file or directory: %s{eoc}\n" static char *builtin_cd_special(char *const av[], char *const env[]) { @@ -28,7 +28,7 @@ static char *builtin_cd_special(char *const av[], char *const env[]) return (NULL); } else if (ft_strcmp(*av, "-") == 0) - target = ft_getenv((char**)env, "OLDPWD"); + target = ft_strdup(ft_getenv((char**)env, "OLDPWD")); else target = *av; return (target); @@ -66,12 +66,15 @@ int builtin_cd(const char *path, char *const av[], char *const envp[]) int i; int opts; char *target; + char *cwd; opts = 0; i = builtin_cd_opts(av, &opts); if (!(target = builtin_cd_special(av + i, envp))) return (0); - builtin_setenv(path, (char*[3]){"OLDPWD", getcwd(NULL, 0)}, envp); + cwd = getcwd(NULL, 0); + builtin_setenv(path, (char*[3]){"OLDPWD", cwd, NULL}, envp); + free(cwd); if (chdir(target)) { ft_printf(CDERR_1, target); @@ -79,6 +82,10 @@ int builtin_cd(const char *path, char *const av[], char *const envp[]) } else if (target != av[i]) ft_printf("%s\n", target); - builtin_setenv(path, (char*[3]){"PWD", getcwd(NULL, 0)}, envp); + cwd = getcwd(NULL, 0); + builtin_setenv(path, (char*[3]){"PWD", cwd, NULL}, envp); + free(cwd); + if (!ft_strcmp(*(av + i), "-")) + free(target); return (0); } diff --git a/42sh/src/builtin/builtin_env.c b/42sh/src/builtin/builtin_env.c index 1262dd6e..64b2f931 100644 --- a/42sh/src/builtin/builtin_env.c +++ b/42sh/src/builtin/builtin_env.c @@ -3,43 +3,134 @@ /* ::: :::::::: */ /* builtin_env.c :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: jhalford +#+ +:+ +#+ */ +/* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/11/28 14:14:20 by jhalford #+# #+# */ -/* Updated: 2017/01/10 13:08:15 by jhalford ### ########.fr */ +/* Updated: 2017/02/17 15:56:55 by gwojda ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" -int builtin_env(const char *path, char *const argv[], char *const envp[]) +/* +** a ajouter dans la lib ? +*/ + +int ft_sstr_found(char **sstr, char *name) { - (void)argv; - (void)envp; - (void)path; + int size; + + size = 0; + if (sstr) + while (sstr[size] && ft_strncmp(name, sstr[size], ft_strlen(name))) + ++size; + return (size); +} + +void ft_sstr_freeone(char **sstr, int index) +{ + char *tmp; + + if (!sstr || !sstr[index]) + return ; + tmp = sstr[index]; + while (sstr[index]) + { + sstr[index] = sstr[index + 1]; + index++; + } + free(tmp); +} + +/* +** +*/ + +static void ft_env_execute(char *const argv[], char **env) +{ + pid_t soon; + char *path; + char *path_exe; + + path = ft_getenv(env, "PATH"); + path_exe = ft_findexec(path, *argv); + if (!path || !path_exe) + { + ft_dprintf(2, "{red}%s: no such file or directory: %s{eoc}\n", + SHELL_NAME, *argv); + return ; + } + if ((soon = fork())) + wait(&soon); + else + set_exitstatus(execve(path_exe, argv, env), 1); + free(path_exe); +} + +static void ft_illegal_opt_env(char c) +{ + ft_dprintf(2, "{red}env: option requires an argument -- %c\n", c); + ft_dprintf(2, "usage: env\t[-iv] [-P utilpath] [-S string]"); + ft_dprintf(2, " [-u name]\n\t\t[name=value ...] "); + ft_dprintf(2, "[utility [argument ...]]{eoc}\n"); +} + +static int ft_check_env_opt(char ***argv, char ***env) +{ + if (!ft_strcmp(**argv, "-i")) + { + ft_sstrfree(*env); + *env = NULL; + ++(*argv); + } + else if (!ft_strcmp(**argv, "-u")) + { + ++(*argv); + if (!**argv) + { + ft_illegal_opt_env('u'); + return (1); + } + ft_sstr_freeone(*env, ft_sstr_found(*env, **argv)); + ++(*argv); + } + else if (***argv == '-') + { + ft_illegal_opt_env(*(**argv + 1)); + return (1); + } return (0); } -/* int builtin_env(char **av, t_data *data) */ -/* { */ -/* int i; */ -/* char **env; */ -/* i = 1; */ -/* env = NULL; */ -/* if (!av[1]) */ -/* { */ -/* ft_sstrprint(data->env, '\n'); */ -/* ft_putchar('\n'); */ -/* } */ -/* else */ -/* { */ -/* while (av[i] && ft_strchr(av[i], '=')) */ -/* { */ -/* env = ft_sstradd(env, av[i]); */ -/* i++; */ -/* } */ -/* if (av[i]) */ -/* ft_cmd_process(av + i); */ -/* } */ -/* return (0); */ -/* } */ +int builtin_env(const char *path, char *const argv[], char *const envp[]) +{ + char **env; + + (void)path; + env = ft_sstrdup((char **)envp); + while (*argv) + { + if (ft_check_env_opt((char ***)&argv, (char ***)&env)) + break ; + while (*argv && ft_strrchr(*argv, '=')) + { + env = ft_sstradd(env, *argv); + ++argv; + } + if (env && (!*argv || (!ft_strcmp(*argv, "env") && !*(argv + 1)))) + { + ft_sstrprint(env, '\n'); + ft_putchar('\n'); + break ; + } + if (*argv && ft_strcmp(*argv, "env")) + { + ft_env_execute(argv, env); + break ; + } + if (*argv) + ++argv; + } + ft_sstrfree(env); + return (0); +} diff --git a/42sh/src/builtin/builtin_exit.c b/42sh/src/builtin/builtin_exit.c index 220886c9..370e60ac 100644 --- a/42sh/src/builtin/builtin_exit.c +++ b/42sh/src/builtin/builtin_exit.c @@ -3,10 +3,10 @@ /* ::: :::::::: */ /* builtin_exit.c :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: jhalford +#+ +:+ +#+ */ +/* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/11/28 14:28:41 by jhalford #+# #+# */ -/* Updated: 2017/02/02 15:04:48 by jhalford ### ########.fr */ +/* Updated: 2017/02/18 16:48:42 by gwojda ### ########.fr */ /* */ /* ************************************************************************** */ @@ -36,6 +36,8 @@ int builtin_exit(const char *path, char *const av[], char *const envp[]) /* status = ft_atoi(ft_getenv(data_singleton()->env, "?")); */ status = 0; } + ft_save_termios(-1); + ft_free_hash_table(); exit(status); return (0); } diff --git a/42sh/src/builtin/builtin_export.c b/42sh/src/builtin/builtin_export.c new file mode 100644 index 00000000..b5fd1b4d --- /dev/null +++ b/42sh/src/builtin/builtin_export.c @@ -0,0 +1,20 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* builtin_export.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/15 11:39:37 by gwojda #+# #+# */ +/* Updated: 2017/02/15 11:46:20 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int builtin_export(const char *path, char *const av[], char *const envp[]) +{ + if (ft_strcmp(av[0], "export") == 0) + av++; + return (builtin_setenv(path, av, envp)); +} diff --git a/42sh/src/builtin/builtin_hash.c b/42sh/src/builtin/builtin_hash.c new file mode 100644 index 00000000..f030a63d --- /dev/null +++ b/42sh/src/builtin/builtin_hash.c @@ -0,0 +1,56 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* builtin_hash.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/18 16:37:43 by gwojda #+# #+# */ +/* Updated: 2017/02/18 16:51:43 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static void ft_hash_lst_print(t_list *list) +{ + while (list) + { + ft_putstr(((t_hash *)list->content)->key); + ft_putchar('='); + ft_putstr(((t_hash *)list->content)->path); + ft_putchar('\n'); + list = list->next; + } +} + +static int ft_hash_opt(char *const av[]) +{ + if (av[1] && !ft_strcmp(av[1], "-r")) + ft_free_hash_table(); + else if (av[1]) + { + ft_dprintf(2, "42sh: hash: invalid option\n"); + ft_dprintf(2, "hash: usage: hash [-r]\n"); + return (1); + } + return (0); +} + +int builtin_hash(const char *path, char *const av[], char *const envp[]) +{ + int i; + + (void)path; + (void)envp; + if (ft_hash_opt(av)) + return (0); + i = 0; + while (i < MAX_HASH) + { + if (g_hash[i]) + ft_hash_lst_print(g_hash[i]); + ++i; + } + return (0); +} diff --git a/42sh/src/builtin/builtin_history.c b/42sh/src/builtin/builtin_history.c new file mode 100644 index 00000000..0c653fbd --- /dev/null +++ b/42sh/src/builtin/builtin_history.c @@ -0,0 +1,38 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* builtin_history.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/24 14:54:53 by gwojda #+# #+# */ +/* Updated: 2017/02/20 20:30:18 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int builtin_history(const char *path, char *const av[], char *const envp[]) +{ + size_t len; + t_list_history *head; + + (void)path; + (void)av; + (void)envp; + head = data_singleton()->line.list_end; + len = 1; + if (!head) + return (0); + if (head && !head->str) + head = head->next; + while (head && head->str) + { + ft_putnc(' ', ft_nbr_len(data_singleton()->line.list_size) + - ft_nbr_len(len)); + ft_printf("%zu %s\n", len, head->str); + ++len; + head = head->next; + } + return (0); +} diff --git a/42sh/src/builtin/builtin_read.c b/42sh/src/builtin/builtin_read.c index 586f3627..cba5e4e6 100644 --- a/42sh/src/builtin/builtin_read.c +++ b/42sh/src/builtin/builtin_read.c @@ -6,7 +6,7 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2017/01/20 15:01:45 by jhalford #+# #+# */ -/* Updated: 2017/01/27 19:40:12 by jhalford ### ########.fr */ +/* Updated: 2017/02/06 14:02:17 by jhalford ### ########.fr */ /* */ /* ************************************************************************** */ @@ -28,14 +28,15 @@ t_readopt g_readtab[] = {0, 0, 0}, }; + int bt_read_loop(t_read *data) { int i; int esc; char buf[2]; - i = 0; esc = 0; + i = 0; if (data->prompt) ft_printf(data->prompt); while (42) @@ -43,12 +44,11 @@ int bt_read_loop(t_read *data) if (read(data->fd, buf, 1) <= 0) return (1); buf[1] = 0; + DG("got input [%x]", *buf); if (!esc && *buf == data->delim) break ; esc = esc ? 0 : !(data->opts & READ_OPT_LR) && (*buf == '\\'); ft_strappend(&data->input, buf); - if (!(data->opts & READ_OPT_LS)) - ft_putchar(*buf); if (*buf == '\n' && !(data->opts & READ_OPT_LR)) ft_putstr("> "); if ((data->opts & READ_OPT_LN) && ++i >= data->nchars) @@ -73,6 +73,7 @@ int bt_read_assign(t_read *data) { if (!(names[1]) || !IFS) { + DG("setting env: %s=%x%x%x", *names, *start, start[1],start[2]); builtin_setenv("setenv", (char*[]){"setenv", *names, start}, NULL); break ; } diff --git a/42sh/src/builtin/builtin_setenv.c b/42sh/src/builtin/builtin_setenv.c index 3c566d6b..3c803bd5 100644 --- a/42sh/src/builtin/builtin_setenv.c +++ b/42sh/src/builtin/builtin_setenv.c @@ -3,10 +3,10 @@ /* ::: :::::::: */ /* builtin_setenv.c :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: jhalford +#+ +:+ +#+ */ +/* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/11/28 14:25:17 by jhalford #+# #+# */ -/* Updated: 2017/01/27 19:00:07 by jhalford ### ########.fr */ +/* Updated: 2017/02/17 13:18:25 by gwojda ### ########.fr */ /* */ /* ************************************************************************** */ @@ -34,8 +34,6 @@ int builtin_setenv(const char *path, char *const av[], char *const envp[]) str = ft_str3join(av[0], "=", av[1]); while ((*env)[i]) { - /* DG("check 2: i=%i, (*env)[i]=%p",i, (*env)[i]); */ - /* DG("content=%s", (*env)[i]); */ if (ft_strcmp((*env)[i], av[0]) == '=') { ft_strdel(&(*env)[i]); diff --git a/42sh/includes/ft_xattr.h b/42sh/src/builtin/builtin_unset.c similarity index 58% rename from 42sh/includes/ft_xattr.h rename to 42sh/src/builtin/builtin_unset.c index 9afadc18..c3afa192 100644 --- a/42sh/includes/ft_xattr.h +++ b/42sh/src/builtin/builtin_unset.c @@ -1,21 +1,18 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* ftxattr.h :+: :+: :+: */ +/* builtin_unset.c :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: jhalford +#+ +:+ +#+ */ +/* By: gwojda +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ -/* Created: 2016/11/07 13:24:05 by jhalford #+# #+# */ -/* Updated: 2016/11/07 13:24:05 by jhalford ### ########.fr */ +/* Created: 2017/02/15 11:43:34 by gwojda #+# #+# */ +/* Updated: 2017/02/15 11:58:22 by gwojda ### ########.fr */ /* */ /* ************************************************************************** */ -#ifndef FT_XATTR_H -# define FT_XATTR_H -# define FT_XATTR_SIZE 10000 -# include -# include +#include "minishell.h" -int ft_xattr_print(char *path); -int ft_xattr_count(char *path); -#endif +int builtin_unset(const char *path, char *const av[], char *const envp[]) +{ + return (builtin_unsetenv(path, av, envp)); +} diff --git a/42sh/src/builtin/is_builtin.c b/42sh/src/builtin/is_builtin.c index b44063b7..597dcb1f 100644 --- a/42sh/src/builtin/is_builtin.c +++ b/42sh/src/builtin/is_builtin.c @@ -6,7 +6,7 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/12/13 13:09:57 by jhalford #+# #+# */ -/* Updated: 2017/02/03 15:31:35 by ariard ### ########.fr */ +/* Updated: 2017/02/20 20:30:54 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,6 +16,8 @@ t_stof g_builtin[] = { {"echo", &builtin_echo}, {"cd", &builtin_cd}, + {"export", &builtin_export}, + {"unset", &builtin_unset}, {"setenv", &builtin_setenv}, {"unsetenv", &builtin_unsetenv}, {"env", &builtin_env}, @@ -24,6 +26,7 @@ t_stof g_builtin[] = {"fg", &builtin_fg}, {"bg", &builtin_bg}, {"read", &builtin_read}, + {"hash", &builtin_hash}, {NULL, NULL}, }; diff --git a/42sh/src/completion/c_binary.c b/42sh/src/completion/c_binary.c new file mode 100644 index 00000000..bccc73d8 --- /dev/null +++ b/42sh/src/completion/c_binary.c @@ -0,0 +1,38 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* c_binary.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: alao +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/09 13:30:57 by alao #+# #+# */ +/* Updated: 2017/02/16 21:03:18 by alao ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "completion.h" + +/* +** Retrieve the path from the env and create a char ** from the PATH pattern. +** The function will cycle through it to find the matching element using the +** c_parser() function. +*/ + +int c_seek_binary(t_data *s, t_comp *c) +{ + char *tmp; + char **paths; + int i; + + i = 0; + tmp = NULL; + if (!(tmp = ft_strdup(ft_getenv(s->env, "PATH")))) + return (-1); + paths = ft_strsplit(tmp, ':'); + c->match = ft_strdup(c->rcmd); + while (paths[i]) + c_parser(c, paths[i++], c->rcmd); + tmp ? ft_memdel((void *)&tmp) : (0); + paths ? ft_sstrfree(paths) : (0); + return (0); +} diff --git a/42sh/src/completion/c_clear.c b/42sh/src/completion/c_clear.c new file mode 100644 index 00000000..815d12b5 --- /dev/null +++ b/42sh/src/completion/c_clear.c @@ -0,0 +1,65 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* c_clear.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: alao +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/10 11:37:43 by alao #+# #+# */ +/* Updated: 2017/02/16 22:03:41 by alao ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "completion.h" + +/* +** Clear the list from the memory +*/ + +int c_clear_lst(t_comp *c) +{ + t_clst *c_lst; + t_clst *p_lst; + + c_lst = c->lst; + c->lst->prev ? (c->lst = c->lst->prev) : (0); + c_lst->prev->next = NULL; + while (c_lst->next) + { + c_lst->name ? ft_memdel((void *)&c_lst->name) : (0); + c_lst->prev = NULL; + p_lst = c_lst; + c_lst = c_lst->next; + p_lst->next = NULL; + p_lst ? ft_memdel((void *)&p_lst) : (0); + } + c_lst->name ? ft_memdel((void *)&c_lst->name) : (0); + c_lst ? ft_memdel((void *)&c_lst) : (0); + c->lst = NULL; + return (0); +} + +/* +** Clear the structure of the autocompletion from the memory and call the above +** function +*/ + +int c_clear(t_data *s) +{ + t_comp *ptr; + + ptr = s->comp; + ptr->rcmd ? ft_memdel((void *)&ptr->rcmd) : (0); + ptr->match ? ft_memdel((void *)&ptr->match) : (0); + ptr->cpath ? ft_memdel((void *)&ptr->cpath) : (0); + ptr->home ? ft_memdel((void *)&ptr->home) : (0); + ptr->pwd ? ft_memdel((void *)&ptr->pwd) : (0); + ptr->start ? ft_memdel((void *)&ptr->start) : (0); + ptr->between ? ft_memdel((void *)&ptr->between) : (0); + ptr->trail ? ft_memdel((void *)&ptr->trail) : (0); + if (ptr->lst && ptr->lst->name) + c_clear_lst(ptr); + s->comp ? ft_memdel((void *)&s->comp) : (0); + s->comp = NULL; + return (0); +} diff --git a/42sh/src/completion/c_files.c b/42sh/src/completion/c_files.c new file mode 100644 index 00000000..dba7bc4f --- /dev/null +++ b/42sh/src/completion/c_files.c @@ -0,0 +1,91 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* c_files.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: alao +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/09 13:31:21 by alao #+# #+# */ +/* Updated: 2017/02/16 22:14:51 by alao ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "completion.h" + +/* +** If the parsing for local file fail. The function is called to check if the +** match is actually a folder. If so, the command is updated with a trailing +** slash (/) using c_updater. +** Exemple: cd folder[tab] to cd folder/ +** Returning 1 if success (trigger an update) or 0. +*/ + +static int c_exclusion_folder(t_comp *c) +{ + DIR *rep; + char *tmp; + char *tmp2; + + tmp = ft_strjoin(c->cpath, c->match); + if ((rep = opendir(tmp)) && (!closedir(rep))) + { + tmp2 = ft_strjoin(c->match, "/"); + c_updater(c, tmp2); + tmp ? ft_memdel((void *)&tmp) : (0); + tmp2 ? ft_memdel((void *)&tmp2) : (0); + return (1); + } + tmp ? ft_memdel((void *)&tmp) : (0); + return (0); +} +/* +** Clear the binary from c->rcmd ans save the result in c->match. Return the +** path part of it if exist or NULL. +*/ + +static char *c_slicer(t_comp *c) +{ + char *tmp; + char *rt; + int i; + + i = 0; + tmp = NULL; + rt = NULL; + while (c->rcmd[i] != ' ') + i++; + c->rcmd[i] == ' ' ? i++ : (0); + if (i == (int)ft_strlen(c->rcmd)) + return (NULL); + tmp = ft_strsub(c->rcmd, i, ft_strlen(c->rcmd) - i); + i = ft_strlen(tmp) - 1; + while (i > 0 && tmp[i] && tmp[i] != '/') + i--; + tmp[i] == '/' ? i++ : (0); + rt = (i == (int)ft_strlen(tmp) - 1) ? NULL : ft_strsub(tmp, 0, i); + if (i <= (int)ft_strlen(tmp) - i + 1) + c->match = ft_strsub(tmp, i, ft_strlen(tmp) - i); + tmp ? ft_memdel((void *)&tmp) : (0); + return (rt); +} + +/* +** Files searching +*/ + +int c_seek_files(t_data *s, t_comp *c) +{ + char *path; + + (void)s; + if (c->cpath == NULL) + { + path = c_slicer(c); + c->cpath = path_solver(c, path, NULL); + path ? ft_memdel((void *)&path) : (0); + } + c_parser(c, c->cpath, c->match); + if (c->lst == NULL) + c_exclusion_folder(c); + return (0); +} diff --git a/42sh/src/completion/c_init.c b/42sh/src/completion/c_init.c new file mode 100644 index 00000000..d9701694 --- /dev/null +++ b/42sh/src/completion/c_init.c @@ -0,0 +1,93 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* c_init.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: alao +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/09 11:21:16 by alao #+# #+# */ +/* Updated: 2017/02/16 22:08:25 by alao ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "completion.h" + +/* +** Trim if there's many commands in a raw separed with a semi colon. +** The cutpoint is saved and also between char **. +*/ + +static char *c_trimmer(char *cmd, int st, int nd) +{ + char *rt; + char *tmp; + int len; + + rt = NULL; + tmp = NULL; + len = ft_strlen(cmd); + if (st == len) + st--; + while (st && cmd[st] && cmd[st] != ';') + st--; + cmd[st] == ';' ? st++ : (0); + while (nd < len && cmd[nd] && cmd[nd] != ';' && cmd[nd] != ' ') + nd++; + rt = ft_strsub(cmd, st, nd - st); + data_singleton()->comp->cutpoint = st; + st = 0; + while (rt[st] == ' ') + st++; + tmp = ft_strsub(rt, st, ft_strlen(rt)); + if (st) + data_singleton()->comp->between = ft_strsub(rt, 0, st); + rt ? ft_memdel((void *)&rt) : (0); + return (tmp); +} + +/* +** Norme function for c_init(). +*/ + +static void c_init_base(t_comp *c) +{ + struct winsize win; + + ioctl(0, TIOCGWINSZ, &win); + c->win_x = win.ws_col; + c->cutpoint = 0; + c->between = NULL; + c->isfolder = 0; + c->match = NULL; + c->cpath = NULL; + c->lst = NULL; + c->trail = NULL; + c->start = NULL; +} + +/* +** Init the completion structure by populating the default value from the main +** structure data and call for the c_matching() function. +*/ + +void c_init(t_data *s, long int input) +{ + + int len_trail; + + if (!(s->comp = (t_comp *)malloc((sizeof(t_comp))))) + return ; + c_init_base(s->comp); + s->comp->rcmd = c_trimmer(s->line.input, s->line.pos, s->line.pos); + len_trail = ft_strlen(s->line.input) - s->line.pos; + if (s->comp->cutpoint) + s->comp->start = ft_strsub(s->line.input, 0, s->comp->cutpoint); + if (ft_strlen(s->line.input) > s->line.pos) + s->comp->trail = ft_strsub(s->line.input, s->line.pos, len_trail); + s->comp->ircmd = s->line.pos; + s->comp->key = input; + s->comp->prompt = s->line.prompt_size; + s->comp->home = ft_strdup(ft_getenv(s->env, "HOME")); + s->comp->pwd = ft_strdup(ft_getenv(s->env, "PWD")); + c_matching(s, s->comp); +} diff --git a/42sh/src/completion/c_matching.c b/42sh/src/completion/c_matching.c new file mode 100644 index 00000000..761f6ef3 --- /dev/null +++ b/42sh/src/completion/c_matching.c @@ -0,0 +1,46 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* c_matching.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: alao +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/10/15 13:27:14 by alao #+# #+# */ +/* Updated: 2017/02/16 21:57:47 by alao ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "completion.h" + +/* +** Start the parsing for the autocompletion. +** Check the first char of the c->rcmd for a . or /. to see if it's a local +** path to search even if there's no space in the command. +** If a space is found in the command. The function will assume it's a binary +** completion that is needed. Else the c_seek_files() is called to search for +** local path along with the binary part separated. +** If any of the other part successfully created a list, the c_sizing is called +** and 1 is returned. The last condition also check is the structure still +** exist. It's only when the c_rematch() called it that it can be the case. +** Else 0 is returned. +*/ + +int c_matching(t_data *s, t_comp *c) +{ + if (c->rcmd[0] == '.' || c->rcmd[0] == '/') + { + c->rcmd[0] == '.' ? c->cpath = path_solver(c, "./", NULL) : 0; + c->rcmd[0] == '/' ? c->cpath = path_solver(c, "/", NULL) : 0; + c_parser(c, c->cpath, c->match); + } + else if (!(ft_strchr(c->rcmd, ' '))) + c_seek_binary(s, c); + else + c_seek_files(s, c); + if (s->comp && c->lst) + { + c_sizing(c); + return (1); + } + return (0); +} diff --git a/42sh/src/completion/c_misc.c b/42sh/src/completion/c_misc.c new file mode 100644 index 00000000..fbdd425a --- /dev/null +++ b/42sh/src/completion/c_misc.c @@ -0,0 +1,52 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* c_misc.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: alao +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/16 22:17:10 by alao #+# #+# */ +/* Updated: 2017/02/16 22:18:43 by alao ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "completion.h" + +/* +** Support: Return the size of a char**. +*/ + +int ft_sstrlen(char **s) +{ + int i; + + i = 0; + while (s[i]) + i++; + return (i); +} + +/* +** Support: Tranform a char** as char* with char*sep in between. +*/ + +char *ft_sstrtostr(char **s, char *sep) +{ + char *tmp; + char *tmp2; + int i; + + tmp = NULL; + tmp2 = NULL; + tmp = ft_strjoin(s[0], sep); + i = 1; + while (s[i]) + { + tmp2 = ft_strjoin(tmp, s[i]); + ft_memdel((void *)&tmp); + tmp = ft_strjoin(tmp2, sep); + ft_memdel((void *)&tmp2); + i++; + } + return (tmp); +} diff --git a/42sh/src/completion/c_output.c b/42sh/src/completion/c_output.c new file mode 100644 index 00000000..6b9f280d --- /dev/null +++ b/42sh/src/completion/c_output.c @@ -0,0 +1,118 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* c_output.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: alao +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/03 13:10:38 by alao #+# #+# */ +/* Updated: 2017/02/16 22:00:38 by alao ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "completion.h" + +/* +** Update of the struct data. +** The broken out command is recomposed as one unique including the choice and +** put back in the main structure. The new cursor position is also updated. +*/ + +static int c_updater_rcmd(t_comp *c) +{ + char *tmp; + char *tmp2; + int new_pos; + + tmp = ft_strjoin(c->start, c->between); + tmp2 = ft_strjoin(tmp, c->rcmd); + c->rcmd ? ft_memdel((void *)&c->rcmd) : (0); + c->rcmd = ft_strjoin(tmp2, c->trail); + if (data_singleton()->line.input) + { + ft_memdel((void *)&data_singleton()->line.input); + data_singleton()->line.input = ft_strdup(c->rcmd); + } + new_pos = ft_strlen(c->start) + ft_strlen(c->between) + ft_strlen(c->rcmd); + data_singleton()->line.pos = new_pos; + tmp ? ft_memdel((void *)&tmp) : (0); + tmp2 ? ft_memdel((void *)&tmp2) : (0); + return (1); +} + +/* +** Output function. Will update the data->line.input along with the +** position of the cursor in data->line.pos. If the autocompletion occur in +** the middle of the command, it will join the trailing part of it. Therefor +** recreating the commands completed. +** Once that done, it will clear all the memory related and return one for the +** line edition module which will then trigger an update on the command line. +*/ + +int c_updater(t_comp *c, char *select) +{ + char *tmp; + char *rt; + + tmp = NULL; + rt = NULL; + if (c->match) + tmp = ft_strsub(c->rcmd, 0, ft_strlen(c->rcmd) - ft_strlen(c->match)); + else + tmp = ft_strdup(c->rcmd); + rt = ft_strjoin(tmp, select); + tmp ? ft_memdel((void *)&tmp) : (0); + c->rcmd ? ft_memdel((void *)&c->rcmd) : (0); + c->rcmd = ft_strdup(rt); + c_updater_rcmd(c); + rt ? ft_memdel((void *)&rt) : (0); + c_clear(data_singleton()); + return (1); +} + +/* +** Keypress handling function. +** +** The function will determine the right behavior depending on the key pressed +** If a delete key is called, the function will clear all the line and delete +** the module memory. +** if a validation key is called, the function will search for the selected +** node and call c_updater(). +** If none of the above behavior is right, the function will call for +** c_rematch() which will recreate the list by adding the keypressed to the +** c->match variable. +** +** RETURN VALUE: +** If the function doesn't require an update of the command line, it will +** return 0. Else it will return 1. +** +** Keypress values that cancel the module: +** 27: Escape +** 127: Backspace +** 2117294875: Delete +** +** Keypress values that validate the choice: +** 10: Enter +** 32: Space +*/ + +int c_gtfo(t_comp *c, long int keypress) +{ + t_clst *ptr; + + if (keypress == 27 || keypress == 127 || keypress == 2117294875) + { + c_term_clear(c); + c_clear(data_singleton()); + return (0); + } + if (keypress == 10 || keypress == 32) + { + ptr = c->lst; + while (!ptr->cursor) + ptr = ptr->next; + c_updater(c, ptr->name); + return (1); + } + return ((c_rematch(c, keypress)) ? (0) : (1)); +} diff --git a/42sh/src/completion/c_parser.c b/42sh/src/completion/c_parser.c new file mode 100644 index 00000000..f611f4df --- /dev/null +++ b/42sh/src/completion/c_parser.c @@ -0,0 +1,80 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* c_parser.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: alao +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/09 13:52:07 by alao #+# #+# */ +/* Updated: 2017/02/16 22:00:49 by alao ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "completion.h" + +/* +** Add the matching element to the list +*/ + +static void c_add_to_lst(t_comp *c, t_clst *node) +{ + if (c->lst == NULL) + { + c->lst = node; + node->next = node; + node->prev = node; + node->cursor = 1; + node->id = 1; + } + else + { + node->id = c->lst->prev->id + 1; + c->lst->prev->next = node; + node->prev = c->lst->prev; + node->next = c->lst; + c->lst->prev = node; + } +} + +/* +** Determine if the element should be added to the list. If so, the node is +** created and the function above is called to add it. +*/ + +static int c_storing(t_comp *c, char *value, unsigned char type) +{ + t_clst *tmp; + + if (ft_strncmp(".", value, 1) == 0 || ft_strncmp("..", value, 2) == 0) + return (0); + if (c->match && ft_strnequ(c->match, value, ft_strlen(c->match)) != 1) + return (0); + if (c->match && ft_strequ(c->match, value)) + return (0); + if (!(tmp = (t_clst *)malloc(sizeof(t_clst)))) + return (-1); + tmp->name = ft_strdup(value); + tmp->len = ft_strlen(tmp->name); + tmp->type = (int)type; + tmp->cursor = 0; + c_add_to_lst(c, tmp); + return (0); +} + +/* +** Cycle through the path specified. +*/ + +int c_parser(t_comp *c, char *path, char *name) +{ + DIR *rep; + struct dirent *dirc; + + (void)name; + if (!(rep = opendir(path))) + return (-1); + while ((dirc = readdir(rep))) + c_storing(c, dirc->d_name, dirc->d_type); + closedir(rep); + return (0); +} diff --git a/42sh/src/completion/c_pathsolver.c b/42sh/src/completion/c_pathsolver.c new file mode 100644 index 00000000..752d874d --- /dev/null +++ b/42sh/src/completion/c_pathsolver.c @@ -0,0 +1,134 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* c_pathsolver.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: alao +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/10/25 18:21:54 by alao #+# #+# */ +/* Updated: 2017/02/16 22:17:53 by alao ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "completion.h" + +/* +** Solve the tilde pattern in the path +*/ + +static char *tilde(t_comp *c, char *cmd) +{ + char *t_home; + char *t_sub; + char *rt; + int l_cmd; + + t_home = NULL; + t_sub = NULL; + rt = NULL; + l_cmd = ft_strlen(cmd); + if ((t_home = ft_strdup(c->home))) + if ((t_sub = ft_strsub(cmd, 1, (l_cmd - 1)))) + rt = ft_strjoin(t_home, t_sub); + t_home ? ft_memdel((void *)&t_home) : (0); + t_sub ? ft_memdel((void *)&t_sub) : (0); + return (rt); +} + +/* +** Advanced dots purge if the first is not enough. Remove a /path/ from +** the raw command if .. is found. Delete the . . +*/ + +static char *dots_purge(char **scwd, char **scmd, int i) +{ + char *tmp; + char *rt; + int j; + + tmp = NULL; + rt = NULL; + ((j = ft_sstrlen(scwd)) > 0) ? (j--) : (0); + (!(scwd[1])) ? (scwd[0] = ft_strdup("/")) : (0); + while (scmd[i] && scwd[0]) + { + if (!(ft_strcmp(scmd[i], ".")) || !(ft_strcmp(scmd[i], scwd[j])) || + !(ft_strcmp(scmd[i], ".."))) + (!(ft_strcmp(scmd[i], ".."))) ? (ft_memdel((void *)&scwd[j])) : (0); + else if ((scwd[j + 1] = ft_strdup(scmd[i]))) + scwd[j + 2] = NULL; + i++; + ((j = ft_sstrlen(scwd)) > 0) ? (j--) : (0); + (!(scwd[0])) ? (scwd[0] = ft_strdup("/")) : (0); + } + rt = ft_sstrtostr(scwd, "/"); + tmp = ft_strjoin("/", rt); + tmp ? ft_memdel((void *)&rt) : (0); + rt = ft_strsub(tmp, 0, (ft_strlen(tmp) - 1)); + tmp ? ft_memdel((void *)&tmp) : (0); + return (rt); +} + +/* +** Solve the dots pattern in the path +*/ + +static char *dots(char *cmd, char *cwd, int i) +{ + char *tmp; + char **scmd; + char **scwd; + + tmp = NULL; + if (!(ft_strcmp(cmd, ".")) || !(ft_strcmp(cmd, "./"))) + return (ft_strdup(cwd)); + if (!ft_strcmp(cmd, "..") && cwd && (i = ft_strlen(cwd))) + { + while (cwd[i] != '/') + i--; + (i) ? (tmp = ft_strncpy(ft_strnew(i), cwd, i)) : (0); + } + if (!tmp && cwd && (i = ft_strlen(cwd))) + { + scmd = ft_strsplit(cmd, '/'); + scwd = ft_strsplit(cwd, '/'); + tmp = dots_purge(scwd, scmd, 0); + scmd ? ft_sstrfree(scmd) : (0); + scwd ? ft_sstrfree(scwd) : (0); + } + if (!cwd) + tmp = ft_strdup("/"); + return (tmp); +} + +/* +** Path solving function. Turn any abstract path to the full version. +*/ + +char *path_solver(t_comp *c, char *cmd, char *cwd) +{ + char *dir; + char *tmp; + char *ncmd; + + dir = NULL; + tmp = NULL; + ncmd = (cmd != NULL) ? ft_strtrim(cmd) : NULL; + cwd = getcwd(cwd, 512); + !cwd ? cwd = ft_strdup(c->pwd) : (0); + if (!ncmd || (*ncmd != '.' && *ncmd != '~' && *ncmd != '/')) + { + tmp = ft_strjoin(cwd, "/"); + dir = ncmd ? ft_strjoin(tmp, ncmd) : ft_strdup(cwd); + tmp ? ft_memdel((void *)&tmp) : (0); + } + else + { + (*ncmd == '~') ? (dir = tilde(c, ncmd)) : (0); + (*ncmd == '.') ? (dir = dots(ncmd, cwd, 0)) : (0); + (*ncmd == '/') ? (dir = ft_strdup(ncmd)) : (0); + } + cwd ? ft_memdel((void *)&cwd) : (0); + ncmd ? ft_memdel((void *)&ncmd) : (0); + return (dir); +} diff --git a/42sh/src/completion/c_printer.c b/42sh/src/completion/c_printer.c new file mode 100644 index 00000000..f43163de --- /dev/null +++ b/42sh/src/completion/c_printer.c @@ -0,0 +1,93 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* c_printer.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: alao +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/10 12:55:39 by alao #+# #+# */ +/* Updated: 2017/02/16 22:11:48 by alao ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "completion.h" + +/* +** Print the name with or without an underline and colored upon file type +** as follow: +** - (4) Folder: Red "\e[1;31m" and a trailing / is added. +** - (10) Symlink: Cyan "\e[96m" and a trailing @ is added. +** If the element is under selection, the video mode is inverted instead. +** The rest of the placeholder is filled with space to align the list. +*/ + +static void c_printer_node(t_clst *lst, int c_sx) +{ + int i; + + i = lst->len; + lst->type == 4 ? ft_putstr_fd("\e[1;31m", 2) : (0); + lst->type == 10 ? ft_putstr_fd("\e[1;96m", 2) : (0); + lst->cursor ? ft_putstr_fd("\e[0;7m", 2) : (0); + ft_putstr_fd(lst->name, 2); + lst->type == 4 ? ft_putstr_fd("/", 2) : (0); + lst->type == 10 ? ft_putstr_fd("@", 2) : (0); + lst->type != 4 && lst->type != 10 ? ft_putstr_fd(" ", 2) : (0); + while (i++ < (c_sx)) + ft_putstr(" "); + ft_putstr_fd("\e[00m", 2); + ft_putstr(" "); +} + +/* +** Cycle through the line to print on the same line the number of time to +** fill it PER LINE and add 2 space after the print to accomodate the +** trailing / for folder and a space in between. +*/ + +static int c_printer_line(t_comp *c, t_clst *lst, int loop, int i) +{ + t_clst *ptr; + + ptr = lst->next; + c_printer_node(lst, c->c_sx); + while (loop) + { + i = 1; + while (i++ < (c->c_line)) + { + if (ptr == c->lst) + return (0); + ptr = ptr->next; + } + if (ptr != c->lst) + { + i = lst->len; + c_printer_node(ptr, c->c_sx); + lst = ptr; + ptr = ptr->next; + } + loop--; + } + return (0); +} + +/* +** Control the number of time it cycle for LINE +*/ + +void c_printer(t_comp *c) +{ + t_clst *ptr; + int loop; + + ptr = c->lst; + loop = c->c_line; + while (loop) + { + c_printer_line(c, ptr, c->c_pline, 1); + loop > 1 ? ft_putstr(tgetstr("do", NULL)) : (0); + ptr = ptr->next; + loop--; + } +} diff --git a/42sh/src/completion/c_rematch.c b/42sh/src/completion/c_rematch.c new file mode 100644 index 00000000..13421f70 --- /dev/null +++ b/42sh/src/completion/c_rematch.c @@ -0,0 +1,76 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* c_rematch.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: alao +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/15 12:03:30 by alao #+# #+# */ +/* Updated: 2017/02/16 22:03:42 by alao ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "completion.h" + +/* +** Recreate a c->match value by adding the new key pressed to it. +*/ + +static int c_refresh_match(t_comp *c, long int keypress) +{ + char *tmp; + char kpconv[2]; + + kpconv[0] = (char)keypress; + kpconv[1] = '\0'; + tmp = c->match ? ft_strjoin(c->match, kpconv) : ft_strdup(kpconv); + c->match ? ft_memdel((void *)&c->match) : (0); + c->match = ft_strdup(tmp); + tmp ? ft_memdel((void *)&tmp) : (0); + tmp = ft_strjoin(c->rcmd, kpconv); + c->rcmd ? ft_memdel((void *)&c->rcmd) : (0); + c->rcmd = ft_strdup(tmp); + c->ircmd++; + tmp ? ft_memdel((void *)&tmp) : (0); + return (0); +} + +/* +** The function is called when the module already exist and a foreign key is +** pressed (like a new letter). If the input key is on the ascii table, the +** previous display of the list is cleared and a new c->match values is +** created. The previous list is then cleared followed by a call to +** c_seek_files() function which will try to recreate a list. If so, the sizing +** is updated and the function return 1. If the research for a new listing fail +** the function return 0 which will tell the next function to cancel the update +** and clear the module memory. +*/ + +int c_rematch(t_comp *c, long int keypress) +{ + if (ft_isascii(keypress)) + { + c_term_clear(c); + c_refresh_match(c, keypress); + c_clear_lst(c); + c_matching(data_singleton(), c); + if (c->lst == NULL) + { + c_clear(data_singleton()); + return (1); + } + else if (c->lst == c->lst->next) + return (1); + else + { + ft_print(keypress); + return(1); + } + } + else + { + c_term_clear(c); + c_clear(data_singleton()); + } + return (0); +} diff --git a/42sh/src/completion/c_sizing.c b/42sh/src/completion/c_sizing.c new file mode 100644 index 00000000..2d7adda9 --- /dev/null +++ b/42sh/src/completion/c_sizing.c @@ -0,0 +1,65 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* c_sizing.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: alao +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/10 08:50:26 by alao #+# #+# */ +/* Updated: 2017/02/16 22:01:47 by alao ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "completion.h" + +/* +** Get the max length from the list +*/ + +static void c_max_length(t_comp *s) +{ + t_clst *tmp; + int max_x; + int max_y; + + if (s->lst && s->lst->name && s->lst == s->lst->next) + { + s->c_sx = s->lst->len; + s->c_sy = 1; + } + else if (s->lst && s->lst->name) + { + max_x = s->lst->len; + max_y = 1; + tmp = s->lst->next; + while (tmp != s->lst) + { + (max_x < tmp->len) ? (max_x = tmp->len) : (0); + max_y++; + tmp = tmp->next; + } + s->c_sx = max_x; + s->c_sy = max_y; + } +} + +/* +** Determine the number of column and row is possible using the list size +** by adding the length of the name plus 2 for the potential trailing / for +** folder. +*/ + +int c_sizing(t_comp *c) +{ + c->lst && c->lst->name ? c_max_length(c) : 0; + c->c_pline = c->win_x / (c->c_sx + 2); + c->c_line = 0; + while ((c->c_line * c->c_pline) < c->c_sy) + c->c_line++; + if (c->win_x < c->c_sx) + { + c->c_pline = 0; + c->c_line = 0; + } + return (0); +} diff --git a/42sh/src/completion/c_terminal.c b/42sh/src/completion/c_terminal.c new file mode 100644 index 00000000..1b5d28a2 --- /dev/null +++ b/42sh/src/completion/c_terminal.c @@ -0,0 +1,86 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* c_terminal.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: alao +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/10/11 10:44:40 by alao #+# #+# */ +/* Updated: 2017/02/16 22:01:37 by alao ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "completion.h" + +/* +** Clear the previous list from the screen and restore the same position. +*/ + +void c_term_clear(t_comp *c) +{ + int i; + int lcmd; + + ft_putstr(tgetstr("do", NULL)); + ft_putstr(tgetstr("cd", NULL)); + ft_putstr(tgetstr("up", NULL)); + i = 0; + lcmd = 0; + c->rcmd ? lcmd += c->ircmd + c->prompt + 1 : 0; + while (i < lcmd) + { + ft_putstr(tgetstr("nd", NULL)); + i++; + } +} + +/* +** Move the terminal up by the number of line needed and move it back up to +** the original position. +*/ + +void c_term_mv_back(t_comp *c) +{ + int i; + int lcmd; + + i = 0; + while (i != (c->c_line)) + { + ft_putstr(tgetstr("up", NULL)); + i++; + } + ft_putstr(tgetstr("cr", NULL)); + i = 0; + lcmd = 0; + c->rcmd ? lcmd += c->ircmd + c->prompt + 1 : 0; + while (i < lcmd) + { + ft_putstr(tgetstr("nd", NULL)); + i++; + } +} + +/* +** Move the terminal down by the number of line needed and move it back up to +** the first line under the prompt +*/ + +void c_term_mv_down(t_comp *c) +{ + int i; + + i = 0; + while (i < c->c_line) + { + ft_putstr(tgetstr("do", NULL)); + ft_putstr(tgetstr("cd", NULL)); + i++; + } + i = 0; + while (i != (c->c_line - 1)) + { + ft_putstr(tgetstr("up", NULL)); + i++; + } +} diff --git a/42sh/src/completion/completion.c b/42sh/src/completion/completion.c new file mode 100644 index 00000000..42705b56 --- /dev/null +++ b/42sh/src/completion/completion.c @@ -0,0 +1,108 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* completion.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: alao +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/09/20 14:50:33 by alao #+# #+# */ +/* Updated: 2017/02/16 22:01:18 by alao ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "completion.h" + +/* +** Function to select the next item in the list if it has already been created +** and if the keypressed is tab. +*/ + +static void c_next_item(t_comp *c) +{ + t_clst *ptr; + + ptr = c->lst; + while (!ptr->cursor) + ptr = ptr->next; + ptr->cursor = 0; + ptr->next->cursor = 1; +} + +/* +** If the list is empty after the parsing, all memory is cleared. +** if it detect a single item list, the command is directly updated. +** If none of the above behavior is right, the terminal is dropped down by +** comp->c_line then the list is printed. Once that done, the previous position +** of the cursor is restored. +*/ + +static int c_dispatcher(t_data *s) +{ + if (s->comp && s->comp->lst == NULL && s->comp->isfolder) + { + c_clear(s); + return (1); + } + if (s->comp && s->comp->lst == NULL) + { + c_clear(s); + return (1); + } + else if (s->comp && s->comp->lst == s->comp->lst->next) + return (c_updater(s->comp, s->comp->lst->name)); + else if (s->comp && s->comp->lst != s->comp->lst->next) + { + c_term_mv_down(s->comp); + c_printer(s->comp); + c_term_mv_back(s->comp); + } + return (0); +} + +/* +** Autocompletion feature. +** +** If the structure of the completion (later called comp) doesn't exist, the +** function will check for a few things. If the current position is zero, it +** will return immediately. Same thing apply if the current position of the +** cursor is not a space. If those condition are not met the comp struct is +** created using c_init(). +** +** If the comp struct already exist at the call of the function, it will check +** which key has been pressed. If the tab key has been used, that mean an other +** item should be selected. This is done using c_next_item(). If the keypress +** is not tab, c_gtfo() is called to know if the command should be updated or +** simply delete all the memory. +** +** The c_dispatcher() is called which will print or update the command +** depending on their respective condition. +*/ + +int completion(long int keypress) +{ + t_data *s; + + s = data_singleton(); + if (s->comp == NULL) + { + if (s->line.pos == 0) + return (0); + if (s->line.input[s->line.pos] != ' ' && + s->line.input[s->line.pos] != '\0') + return (0); + c_init(s, keypress); + if (s->comp == NULL) + return (1); + } + else + { + if (keypress == TOUCHE_TAB) + c_next_item(s->comp); + else + { + if (c_gtfo(s->comp, keypress)) + return (1); + } + } + return (c_dispatcher(s)); +} diff --git a/42sh/src/exec/bad_fd.c b/42sh/src/exec/bad_fd.c new file mode 100644 index 00000000..031c26cf --- /dev/null +++ b/42sh/src/exec/bad_fd.c @@ -0,0 +1,20 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* bad_fd.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/06 22:32:43 by jhalford #+# #+# */ +/* Updated: 2017/02/07 16:02:12 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int bad_fd(int fd) +{ + ft_dprintf(2, "{red}%s: %i: Bad file descriptor{eoc}\n", + SHELL_NAME, fd); + return (1); +} diff --git a/42sh/src/exec/exec_ampersand.c b/42sh/src/exec/exec_ampersand.c index 55da0220..f69ed62c 100644 --- a/42sh/src/exec/exec_ampersand.c +++ b/42sh/src/exec/exec_ampersand.c @@ -14,10 +14,10 @@ int exec_ampersand(t_btree **ast) { - if (SHELL_HAS_JOBC(data_singleton()->opts)) + if (SH_HAS_JOBC(data_singleton()->opts)) data_singleton()->exec.job.attributes |= JOB_BG; ft_exec(&(*ast)->left); - if (SHELL_HAS_JOBC(data_singleton()->opts)) + if (SH_HAS_JOBC(data_singleton()->opts)) data_singleton()->exec.job.attributes &= ~JOB_BG; ft_exec(&(*ast)->right); diff --git a/42sh/src/exec/exec_command.c b/42sh/src/exec/exec_command.c index dace8040..c6ddecb2 100644 --- a/42sh/src/exec/exec_command.c +++ b/42sh/src/exec/exec_command.c @@ -6,7 +6,7 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/11/14 17:28:14 by jhalford #+# #+# */ -/* Updated: 2017/02/05 22:09:37 by ariard ### ########.fr */ +/* Updated: 2017/02/20 20:32:10 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ @@ -27,11 +27,13 @@ static char **token_to_argv(t_astnode *node) while (ld) { content = ld->content; - expand = glob(content[0], (unsigned char *)content[1]); - index = -1; - while (expand[++index]) - my_tab = ft_sstradd(my_tab, expand[index]); - ft_tabdel(&expand); + if ((expand = glob(content[0], (unsigned char *)content[1], (unsigned char *)content[2]))) + { + index = -1; + while (expand[++index]) + my_tab = ft_sstradd(my_tab, expand[index]); + ft_tabdel(&expand); + } ld = ld->next; } return (my_tab); @@ -63,9 +65,7 @@ int exec_command(t_btree **ast) job->pgid = 0; } } - p->av = NULL; - p->pid = 0; - p->attributes &= ~(PROCESS_STATE_MASK | PROCESS_TYPE_MASK); + process_reset(p); // btree_delone(ast, &ast_free); return (0); } diff --git a/42sh/src/exec/exec_less.c b/42sh/src/exec/exec_less.c index 3629ff65..50797abd 100644 --- a/42sh/src/exec/exec_less.c +++ b/42sh/src/exec/exec_less.c @@ -6,7 +6,7 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/11/14 17:27:08 by jhalford #+# #+# */ -/* Updated: 2017/02/05 22:12:02 by ariard ### ########.fr */ +/* Updated: 2017/02/20 20:32:26 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ diff --git a/42sh/src/exec/exec_pipe.c b/42sh/src/exec/exec_pipe.c index 1ba905b0..142f18c3 100644 --- a/42sh/src/exec/exec_pipe.c +++ b/42sh/src/exec/exec_pipe.c @@ -6,7 +6,7 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/11/27 21:13:23 by jhalford #+# #+# */ -/* Updated: 2017/02/05 22:14:32 by ariard ### ########.fr */ +/* Updated: 2017/02/20 20:32:52 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ @@ -22,7 +22,7 @@ int exec_pipe(t_btree **ast) data = data_singleton(); p = &data_singleton()->exec.process; pipe(fds); - DG("pipe %i->%i", fds[PIPE_WRITE], fds[PIPE_READ]); + /* DG("pipe %i->%i", fds[PIPE_WRITE], fds[PIPE_READ]); */ p->fdout = fds[PIPE_WRITE]; start = IS_PIPESTART(p->attributes); p->toclose = fds[PIPE_READ]; diff --git a/42sh/src/exec/exec_great.c b/42sh/src/exec/exec_redir.c similarity index 72% rename from 42sh/src/exec/exec_great.c rename to 42sh/src/exec/exec_redir.c index 8190f929..e8245a67 100644 --- a/42sh/src/exec/exec_great.c +++ b/42sh/src/exec/exec_redir.c @@ -1,28 +1,27 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* exec_great.c :+: :+: :+: */ +/* exec_redir.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/11/14 17:27:51 by jhalford #+# #+# */ -/* Updated: 2017/02/05 22:11:18 by ariard ### ########.fr */ +/* Updated: 2017/02/20 20:33:34 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ #include "exec.h" -int exec_great(t_btree **ast) +int exec_redir(t_btree **ast) { t_astnode *node; - int fd; + t_process *p; + p = &data_singleton()->exec.process; node = (*ast)->item; - fd = open(node->data.redir.word.word, O_WRONLY | O_TRUNC | O_CREAT, 0644); - data_singleton()->exec.process.fdout = fd; + node->data.redir.type = node->type; + ft_lsteadd(&p->redirs, ft_lstnew(&node->data.redir,sizeof(node->data.redir))); ft_exec(&(*ast)->left); - data_singleton()->exec.process.fdout = STDOUT; - // btree_delone(ast, &ast_free); return (0); } diff --git a/42sh/src/exec/fd_is_valid.c b/42sh/src/exec/fd_is_valid.c new file mode 100644 index 00000000..bcb6cdda --- /dev/null +++ b/42sh/src/exec/fd_is_valid.c @@ -0,0 +1,18 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* fd_is_valid.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/03 13:46:40 by jhalford #+# #+# */ +/* Updated: 2017/02/06 22:54:19 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int fd_is_valid(int fd) +{ + return (fcntl(fd, F_GETFD) != -1 || errno != EBADF); +} diff --git a/42sh/src/exec/ft_exec.c b/42sh/src/exec/ft_exec.c index 1baf929c..dd19e60d 100644 --- a/42sh/src/exec/ft_exec.c +++ b/42sh/src/exec/ft_exec.c @@ -6,7 +6,7 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/11/27 20:30:32 by jhalford #+# #+# */ -/* Updated: 2017/02/06 21:03:47 by ariard ### ########.fr */ +/* Updated: 2017/02/20 21:03:42 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ @@ -30,6 +30,8 @@ t_execmap g_execmap[] = {TK_UNTIL, &exec_until}, {TK_COMMAND, &exec_command}, {TK_SUBSHELL, &exec_command}, + {TK_REDIR, &exec_redir}, + {TK_COMMAND | TK_SUBSHELL, &exec_command}, {0, 0}, }; @@ -54,4 +56,4 @@ int ft_exec(t_btree **ast) i++; } return (0); -} + diff --git a/42sh/src/exec/launch_process.c b/42sh/src/exec/launch_process.c index 1952d096..204a76bb 100644 --- a/42sh/src/exec/launch_process.c +++ b/42sh/src/exec/launch_process.c @@ -3,10 +3,10 @@ /* ::: :::::::: */ /* launch_process.c :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: jhalford +#+ +:+ +#+ */ +/* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/12/13 14:20:45 by jhalford #+# #+# */ -/* Updated: 2017/02/03 14:39:16 by ariard ### ########.fr */ +/* Updated: 2017/02/20 21:03:48 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ @@ -24,7 +24,11 @@ int launch_process(t_process *p) set_exitstatus(127, 1); } else if (p->attributes & PROCESS_BUILTIN && IS_PIPESINGLE(p->attributes)) + { + if (process_redirect(p)) + return (1); set_exitstatus((*p->execf)(p->path, p->av, data_singleton()->env), 1); + } else { p->attributes &= ~PROCESS_STATE_MASK; @@ -41,7 +45,8 @@ int launch_process(t_process *p) { process_setgroup(p, 0); process_setsig(); - process_redirect(p); + if (process_redirect(p)) + exit (1); (*p->execf)(p->path, p->av, data_singleton()->env); exit(43); } @@ -52,7 +57,7 @@ int launch_process(t_process *p) return (0); } else if (pid == -1) - ft_dprintf(2, "{red}internal fork error{eoc}\n"); + ft_dprintf(2, "{red}%s: internal fork error{eoc}\n", SHELL_NAME); } return (1); } diff --git a/42sh/src/exec/process_redirect.c b/42sh/src/exec/process_redirect.c index 77830bb0..33654306 100644 --- a/42sh/src/exec/process_redirect.c +++ b/42sh/src/exec/process_redirect.c @@ -6,25 +6,54 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/11/29 16:04:18 by jhalford #+# #+# */ -/* Updated: 2017/01/10 14:31:15 by jhalford ### ########.fr */ +/* Updated: 2017/02/07 17:36:46 by jhalford ### ########.fr */ /* */ /* ************************************************************************** */ #include "exec.h" +t_redirmap g_redirmap[] = +{ + {TK_LESS, redirect_less}, + {TK_GREAT, redirect_great}, + {TK_DLESS, redirect_dless}, + {TK_DGREAT, redirect_dgreat}, + {TK_LESSAND, redirect_lessand}, + {TK_GREATAND, redirect_greatand}, + {0, NULL}, +}; + int process_redirect(t_process *p) { + t_list *redirs; + t_redir *redir; + int i; + + redirs = p->redirs; + while (redirs) + { + redir = redirs->content; + if (redir->n > 9) + return (bad_fd(redir->n)); + i = 0; + while (g_redirmap[i].type) + { + if (g_redirmap[i].type == redir->type) + { + if ((g_redirmap[i].f)(redir)) + return (1); + break ; + } + i++; + } + redirs = redirs->next; + } if (p->toclose != STDIN) close(p->toclose); if (p->fdin != STDIN) - { - dup2(p->fdin, STDIN); - close(p->fdin); - } + dup2_close(p->fdin, STDIN); if (p->fdout != STDOUT) - { - dup2(p->fdout, STDOUT); - close(p->fdout); - } + dup2_close(p->fdout, STDOUT); + ft_lstdel(&p->redirs, ft_lst_cfree); return (0); } diff --git a/42sh/src/exec/process_reset.c b/42sh/src/exec/process_reset.c index 4b3c02a9..b90a131e 100644 --- a/42sh/src/exec/process_reset.c +++ b/42sh/src/exec/process_reset.c @@ -1,8 +1,22 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* process_reset.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/07 17:44:22 by jhalford #+# #+# */ +/* Updated: 2017/02/07 17:48:22 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + #include "exec.h" -void process_reset(void) +void process_reset(t_process *p) { - t_data *data; - - data = data_singleton(); + process_resetfds(); + p->av = NULL; + p->pid = 0; + p->redirs = NULL; + p->attributes &= ~(PROCESS_STATE_MASK | PROCESS_TYPE_MASK); } diff --git a/42sh/src/lexer/token_expand_var.c b/42sh/src/exec/process_resetfds.c similarity index 60% rename from 42sh/src/lexer/token_expand_var.c rename to 42sh/src/exec/process_resetfds.c index 9743d062..dbc9403a 100644 --- a/42sh/src/lexer/token_expand_var.c +++ b/42sh/src/exec/process_resetfds.c @@ -1,28 +1,23 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* token_expand_var.c :+: :+: :+: */ +/* process_resetfds.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ -/* Created: 2017/01/10 14:57:53 by jhalford #+# #+# */ -/* Updated: 2017/01/27 15:56:40 by wescande ### ########.fr */ +/* Created: 2017/02/07 17:39:14 by jhalford #+# #+# */ +/* Updated: 2017/02/07 17:50:52 by jhalford ### ########.fr */ /* */ /* ************************************************************************** */ -#include "lexer.h" +#include "minishell.h" -void token_expand_var(t_token *token) +void process_resetfds(void) { - char *dollar; - char *val; + t_exec *exec; - dollar = ft_strchr(token->data, '$'); - if (!dollar[1]) - return ; - val = ft_getenv(data_singleton()->env, dollar + 1); - *dollar = 0; - if (val) - while (*val) - token_append(token, *val++, 1); + exec = &data_singleton()->exec; + dup2(exec->fd0save, 0); + dup2(exec->fd1save, 1); + dup2(exec->fd2save, 2); } diff --git a/42sh/src/exec/process_setexec.c b/42sh/src/exec/process_setexec.c index 6093aec2..d184531f 100644 --- a/42sh/src/exec/process_setexec.c +++ b/42sh/src/exec/process_setexec.c @@ -3,10 +3,10 @@ /* ::: :::::::: */ /* process_setexec.c :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: jhalford +#+ +:+ +#+ */ +/* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/12/13 17:07:10 by jhalford #+# #+# */ -/* Updated: 2017/01/30 18:29:23 by ariard ### ########.fr */ +/* Updated: 2017/02/20 20:42:02 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,6 +14,7 @@ int process_setexec(t_type type, t_process *p) { + p->path = NULL; if (type == TK_SUBSHELL) { p->execf = &execve; @@ -21,15 +22,16 @@ int process_setexec(t_type type, t_process *p) p->path = ft_strdup(p->av[0]); } else if ((p->execf = is_builtin(p))) + { p->attributes |= PROCESS_BUILTIN; + } else if (ft_strchr(p->av[0], '/')) { p->execf = &execve; p->attributes |= PROCESS_SCRIPT; p->path = ft_strdup(p->av[0]); } - else if ((p->path = ft_findexec(ft_getenv( - data_singleton()->env, "PATH"), p->av[0]))) + else if (ft_hash(p)) { p->execf = &execve; p->attributes |= PROCESS_BINARY; diff --git a/42sh/src/exec/process_setgroup.c b/42sh/src/exec/process_setgroup.c index 186ed6d9..a7ada487 100644 --- a/42sh/src/exec/process_setgroup.c +++ b/42sh/src/exec/process_setgroup.c @@ -16,11 +16,13 @@ int process_setgroup(t_process *p, pid_t pid) { t_job *j; + t_data *data; (void)p; - if (!SHELL_HAS_JOBC(data_singleton()->opts)) + data = data_singleton(); + if (!SH_HAS_JOBC(data->opts)) return (0); - j = &data_singleton()->exec.job; + j = &data->exec.job; if (!j->pgid) j->pgid = pid ? pid : getpid(); setpgid(pid, j->pgid); diff --git a/42sh/includes/mytime.h b/42sh/src/exec/redirect_dgreat.c similarity index 58% rename from 42sh/includes/mytime.h rename to 42sh/src/exec/redirect_dgreat.c index f9678127..62e01058 100644 --- a/42sh/includes/mytime.h +++ b/42sh/src/exec/redirect_dgreat.c @@ -1,34 +1,29 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* mytime.h :+: :+: :+: */ +/* redirect_dgreat.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ -/* Created: 2016/11/25 11:43:12 by jhalford #+# #+# */ -/* Updated: 2017/02/03 14:42:38 by ariard ### ########.fr */ +/* Created: 2017/02/06 22:07:37 by jhalford #+# #+# */ +/* Updated: 2017/02/06 22:27:10 by jhalford ### ########.fr */ /* */ /* ************************************************************************** */ -#ifndef MYTIME_H -# define MYTIME_H -# include "libft.h" +#include "exec.h" -struct s_mytime +int redirect_dgreat(t_redir *redir) { - char *year; - char *month; - char *day; - char *hour; - char *min; - char *sec; -}; + int fdold; + int fdnew; -typedef struct s_mytime t_mytime; - -int ft_time_isrecent(time_t event); - -t_mytime *ft_mytime_get(time_t epoch); -void ft_mytime_free(t_mytime **time); - -#endif + fdnew = redir->n; + if ((fdold = open(redir->word.word, + O_WRONLY | O_CREAT | O_APPEND, 0644)) < 0) + { + DG("open errno=%i", errno); + exit(1); + } + dup2(fdold, fdnew); + return (0); +} diff --git a/42sh/src/exec/redirect_dless.c b/42sh/src/exec/redirect_dless.c new file mode 100644 index 00000000..36f4a25a --- /dev/null +++ b/42sh/src/exec/redirect_dless.c @@ -0,0 +1,26 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* redirect_dless.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Updated: 2017/02/07 16:05:09 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "exec.h" + +int redirect_dless(t_redir *redir) +{ + int fds[2]; + char *str; + + pipe(fds); + str = redir->word.word; + write(fds[PIPE_WRITE], str, ft_strlen(str)); + close(fds[PIPE_WRITE]); + dup2(fds[PIPE_READ], 0); + close(fds[PIPE_READ]); + return (0); +} diff --git a/42sh/src/exec/redirect_great.c b/42sh/src/exec/redirect_great.c new file mode 100644 index 00000000..bd6e170a --- /dev/null +++ b/42sh/src/exec/redirect_great.c @@ -0,0 +1,29 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* redirect_great.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/06 22:03:53 by jhalford #+# #+# */ +/* Updated: 2017/02/06 22:42:05 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "exec.h" + +int redirect_great(t_redir* redir) +{ + int fdold; + int fdnew; + + fdnew = redir->n; + if ((fdold = open(redir->word.word, + O_WRONLY | O_CREAT | O_TRUNC, 0644)) < 0) + { + DG("open errno=%i", errno); + exit(1); + } + dup2(fdold, fdnew); + return (0); +} diff --git a/42sh/src/exec/redirect_greatand.c b/42sh/src/exec/redirect_greatand.c new file mode 100644 index 00000000..70658424 --- /dev/null +++ b/42sh/src/exec/redirect_greatand.c @@ -0,0 +1,37 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* redirect_greatand.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/06 22:12:31 by jhalford #+# #+# */ +/* Updated: 2017/02/07 17:54:40 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "exec.h" + +int redirect_greatand(t_redir *redir) +{ + int fdold; + int fdnew; + + DG("redir greatand"); + if (redir->close) + { + close(redir->n); + return (0); + } + if (redir->word.fd == redir->n) + return (0); + if (redir->word.fd > 9) + return (bad_fd(redir->word.fd)); + fdold = redir->word.fd; + fdnew = redir->n; + if (fd_is_valid(fdold)) + dup2_close(fdold, fdnew); + else + return (bad_fd(fdold)); + return (0); +} diff --git a/42sh/src/exec/exec_dgreat.c b/42sh/src/exec/redirect_less.c similarity index 59% rename from 42sh/src/exec/exec_dgreat.c rename to 42sh/src/exec/redirect_less.c index e045ee8c..8619db29 100644 --- a/42sh/src/exec/exec_dgreat.c +++ b/42sh/src/exec/redirect_less.c @@ -1,28 +1,29 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* exec_dgreat.c :+: :+: :+: */ +/* redirect_less.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ -/* Created: 2016/11/28 18:15:13 by jhalford #+# #+# */ -/* Updated: 2017/02/05 22:10:53 by ariard ### ########.fr */ +/* Created: 2017/02/06 22:09:53 by jhalford #+# #+# */ +/* Updated: 2017/02/20 20:42:53 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ #include "exec.h" -int exec_dgreat(t_btree **ast) +int redirect_less(t_redir *redir) { - t_astnode *node; - int fd; + int fdold; + int fdnew; - node = (*ast)->item; - fd = open(node->data.redir.word.word, O_WRONLY | O_APPEND | O_CREAT, 0644); - data_singleton()->exec.process.fdout = fd; - ft_exec(&(*ast)->left); - data_singleton()->exec.process.fdout = STDOUT; - -// btree_delone(ast, &ast_free); + fdnew = redir->n; + if ((fdold = open(redir->word.word, O_RDONLY)) < 0) + { + ft_dprintf(2, "{red}%s: no such file or directory: %s{eoc}\n", + SHELL_NAME, redir->word.word); + exit (1); + } + dup2(fdold, fdnew); return (0); } diff --git a/42sh/src/exec/redirect_lessand.c b/42sh/src/exec/redirect_lessand.c new file mode 100644 index 00000000..15da4123 --- /dev/null +++ b/42sh/src/exec/redirect_lessand.c @@ -0,0 +1,39 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* redirect_lessand.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/06 22:11:18 by jhalford #+# #+# */ +/* Updated: 2017/02/07 17:54:57 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "exec.h" + +int redirect_lessand(t_redir *redir) +{ + int fdold; + int fdnew; + + if (redir->close) + { + close(redir->n); + return (0); + } + if (redir->word.fd == redir->n) + return (0); + if (redir->word.fd > 9) + return (bad_fd(redir->word.fd)); + fdold = redir->word.fd; + fdnew = redir->n; + if (fd_is_valid(fdold)) + { + dup2(fdold, fdnew); + close(fdold); + } + else + return (bad_fd(fdold)); + return (0); +} diff --git a/42sh/src/exec/set_exitstatus.c b/42sh/src/exec/set_exitstatus.c index ed05ea7b..ffb502da 100644 --- a/42sh/src/exec/set_exitstatus.c +++ b/42sh/src/exec/set_exitstatus.c @@ -6,7 +6,7 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/11/28 14:25:17 by jhalford #+# #+# */ -/* Updated: 2017/01/30 21:05:42 by ariard ### ########.fr */ +/* Updated: 2017/02/20 20:43:03 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ @@ -27,7 +27,7 @@ void set_exitstatus(int status, int override) exitval = 128 + WTERMSIG(status); else { - DG("fail: process was not exited nor signaled."); + DG("%s: process was not exited nor signaled.", SHELL_NAME); return ; } } diff --git a/42sh/src/lexer/command_getoutput.c b/42sh/src/glob/command_getoutput.c similarity index 98% rename from 42sh/src/lexer/command_getoutput.c rename to 42sh/src/glob/command_getoutput.c index 8982d96f..00ef6581 100644 --- a/42sh/src/lexer/command_getoutput.c +++ b/42sh/src/glob/command_getoutput.c @@ -34,7 +34,7 @@ char *command_getoutput(char *command) ast = btree_create_node(&item, sizeof(item)); pipe(fds); exec->process.fdout = fds[PIPE_WRITE]; - ft_exec(&ast); + exec_command(&ast); exec->process.fdout = STDOUT; close(fds[PIPE_WRITE]); while ((ret = read(fds[PIPE_READ], buf, BUF_SIZE))) diff --git a/42sh/src/glob/dir_glob.c b/42sh/src/glob/dir_glob.c index 3ed4a660..8dc2d0da 100644 --- a/42sh/src/glob/dir_glob.c +++ b/42sh/src/glob/dir_glob.c @@ -6,7 +6,7 @@ /* By: wescande +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2017/01/30 12:07:16 by wescande #+# #+# */ -/* Updated: 2017/02/01 19:49:44 by wescande ### ########.fr */ +/* Updated: 2017/02/07 19:48:12 by wescande ### ########.fr */ /* */ /* ************************************************************************** */ @@ -20,14 +20,12 @@ int is_directory(const char *path) return (S_ISDIR(path_stat.st_mode)); } -static int dir_list_content(t_glob *gl, char **str, const char *pat, +static void dir_list_content(t_glob *gl, char **str, char *pat, int recursive) { - int ret; char *path_tmp; - ret = 0; - if (ft_strcmp(str[1], ".") && ft_strcmp(str[1], "..")) + if (str[1][0] != '.') { if (*str[0] == '/' && !*(str[0] + 1)) path_tmp = ft_strjoin(str[0], str[1]); @@ -36,16 +34,18 @@ static int dir_list_content(t_glob *gl, char **str, const char *pat, if (recursive) dir_research(gl, path_tmp, pat, recursive); gl->pat = pat; - if (match_pattern(gl, str[1], path_tmp) && ++ret) - ft_ld_pushfront(&gl->match, ft_strdup(path_tmp + 2 * + if (match_pattern(gl, str[1], path_tmp)) + { + gl->found = 1; + ft_ld_pushfront(&gl->match, ft_strdup(path_tmp + gl->cur_dir * 2 * (path_tmp[0] == '.' && path_tmp[1] == '/'))); + } ft_strdel(&path_tmp); } - return (ret); } int dir_research(t_glob *gl, char *p, - const char *pat, int recursive) + char *pat, int recursive) { DIR *dir; struct dirent *in; @@ -56,7 +56,7 @@ int dir_research(t_glob *gl, char *p, { dir = opendir(p); while ((in = readdir(dir))) - ret += dir_list_content(gl, + dir_list_content(gl, (char *[2]){p, in->d_name}, pat, recursive); closedir(dir); } diff --git a/42sh/src/glob/esc_print.c b/42sh/src/glob/esc_print.c new file mode 100644 index 00000000..8938302d --- /dev/null +++ b/42sh/src/glob/esc_print.c @@ -0,0 +1,29 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* esc_print.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/17 15:38:14 by jhalford #+# #+# */ +/* Updated: 2017/02/20 18:49:02 by wescande ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "glob.h" + +void esc_print(char *str, unsigned char *esc) +{ + char *cur; + + cur = str; + while (*cur) + { + if (is_char_esc(esc, str, cur)) + printf("\\%c", *cur); + else + printf("%c", *cur); + ++cur; + } + printf("\n"); +} diff --git a/42sh/src/glob/expand_bquote.c b/42sh/src/glob/expand_bquote.c new file mode 100644 index 00000000..d24e3892 --- /dev/null +++ b/42sh/src/glob/expand_bquote.c @@ -0,0 +1,138 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* expand_bquote.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/17 17:47:53 by wescande #+# #+# */ +/* Updated: 2017/02/20 19:11:11 by wescande ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "glob.h" + +static void expand_all_bquote(t_bquote *me, char *content, + char *ifs) +{ + char *content2; + + while ((content2 = ft_strtok(NULL, ifs))) + { + ft_ld_pushfront(me->wk, gen_tab(ft_strdup(content), + calc_expand_esc(me->esc, 0, + (int[2]){ft_strlen(content), 1}, (int[2]){0, 0}), + calc_expand_esc(me->esc2, 0, + (int[2]){ft_strlen(content), 1}, (int[2]){0, 0}), 0)); + content = content2; + } + ft_ld_pushfront(me->wk, gen_tab(ft_strjoin(content, me->s2), + calc_expand_esc(me->esc, 0, + (int[2]){ft_strlen(content), 1}, + (int[2]){ft_strlen(me->s1) + ft_strlen(me->mid), + ft_strlen(me->s2)}), + calc_expand_esc(me->esc2, ft_strlen(me->s1), + (int[2]){ft_strlen(content), 1}, + (int[2]){ft_strlen(me->s1) + ft_strlen(me->mid), + ft_strlen(me->s2)}), + 0)); +} + +static void init_expand(t_bquote *me, char *content, int esc) +{ + char *ifs; + char *content2; + + ifs = esc ? NULL : ft_getenv(data_singleton()->env, "IFS"); + content = ft_strtok(content, ifs); + if (!(content2 = ft_strtok(NULL, ifs))) + ft_ld_pushfront(me->wk, gen_tab(ft_strjoinf(ft_strjoin(me->s1, content), + me->s2, 1), + calc_expand_esc(me->esc, ft_strlen(me->s1), + (int[2]){ft_strlen(content), 1}, + (int[2]){ft_strlen(me->s1) + ft_strlen(me->mid), + ft_strlen(me->s2)}), + calc_expand_esc(me->esc2, ft_strlen(me->s1), + (int[2]){ft_strlen(content), 1}, + (int[2]){ft_strlen(me->s1) + ft_strlen(me->mid), + ft_strlen(me->s2)}), 0)); + else + { + ft_ld_pushfront(me->wk, gen_tab(ft_strjoin(me->s1, content), + calc_expand_esc(me->esc, ft_strlen(me->s1), + (int[2]){ft_strlen(content), 1}, (int[2]){0, 0}), + calc_expand_esc(me->esc2, ft_strlen(me->s1), + (int[2]){ft_strlen(content), 1}, (int[2]){0, 0}), 0)); + expand_all_bquote(me, content2, ifs); + } +} + +static char *get_output(char *command) +{ + char *output; + int len; + + output = command_getoutput(command); + len = ft_strlen(output); + while (output[--len] == '\n') + output[len] = '\0'; + return (output); +} + +static int search_bquote(t_bquote *me) +{ + char *sta; + char *content; + + sta = NULL; + while (*me->str) + { + sta = *me->str == '`' && !sta + && !is_char_esc(me->esc2, CH(*me->wk)[0], me->str) ? me->str : sta; + if (sta && *me->str == '`' && me->str != sta + && !is_char_esc(me->esc2, CH(*me->wk)[0], me->str)) + { + me->mid = ft_strsub(sta, 1, me->str - sta - 1); + me->s1 = ft_strsub(CH(*me->wk)[0], 0, sta - CH(*me->wk)[0]); + me->s2 = ft_strdup(me->str + 1); + content = get_output(me->mid); + init_expand(me, content, is_char_esc(me->esc, CH(*me->wk)[0], sta)); + ft_strdel(&me->mid); + ft_strdel(&me->s1); + ft_strdel(&me->s2); + ft_strdel(&content); + return (1); + } + ++me->str; + } + return (0); +} + +void expand_bquote(t_glob *gl) +{ + t_ld *tmp; + t_bquote me; + int do_it; + + ft_ld_pushfront(&gl->m_pat, gen_tab(gl->pat, gl->esc, gl->esc2, 0)); + me = (t_bquote){NULL, NULL, NULL, NULL, NULL, NULL, NULL}; + do_it = 1; + while ((gl->m_pat = ft_ld_front(gl->m_pat)) && do_it) + { + do_it = 0; + while (gl->m_pat && !do_it) + { + me.wk = &gl->m_pat; + me.esc = UCH(gl->m_pat)[1]; + me.esc2 = UCH(gl->m_pat)[2]; + me.str = CH(gl->m_pat)[0]; + if ((tmp = gl->m_pat) && + (do_it = search_bquote(&me)) == 1) + ft_ld_del(&tmp, &ft_tabdel); + if (!gl->m_pat->next) + break ; + gl->m_pat = gl->m_pat->next; + } + } + ft_ld_reverse(&gl->m_pat); +} diff --git a/42sh/src/glob/expand_brace.c b/42sh/src/glob/expand_brace.c index 6aa16d58..13cacf4d 100644 --- a/42sh/src/glob/expand_brace.c +++ b/42sh/src/glob/expand_brace.c @@ -6,7 +6,7 @@ /* By: wescande +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2017/01/12 19:00:29 by wescande #+# #+# */ -/* Updated: 2017/01/31 23:20:38 by wescande ### ########.fr */ +/* Updated: 2017/02/20 18:54:19 by wescande ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,27 +17,36 @@ ** pattern searched are {ab, cd}. ** return is t_ld which first param is ab and second is cd ** input parameters are : -** -char *pat -> pattern string to be looking for expand +** -t_glob *gl -> struct of expanding */ -static char **gen_tab(const char *pat, - const unsigned char *esc, int dup) +char **gen_tab(const char *pat, + const unsigned char *esc, + const unsigned char *esc2, + int dup) { char **my_tab; - if (!(my_tab = (char **)malloc(sizeof(char *) * 3))) + if (!(my_tab = (char **)malloc(sizeof(char *) * (esc2 ? 4 : 3)))) return (NULL); if (dup) { my_tab[0] = ft_strdup(pat); my_tab[1] = ft_strdup((const char *)esc); + if (esc2) + my_tab[2] = ft_strdup((const char *)esc2); } else { my_tab[0] = (char *)pat; my_tab[1] = (char *)esc; + if (esc2) + my_tab[2] = (char *)esc2; } - my_tab[2] = NULL; + if (esc2) + my_tab[3] = NULL; + else + my_tab[2] = NULL; return (my_tab); } @@ -49,24 +58,24 @@ static void iter_on_each(t_expand *me) unsigned char *second; t_ld *wk_tmp; - i = -1; + i = ft_tablen(me->split); wk_tmp = *me->wk; - while (me->split[++i]) + while (i--) { first = ft_strjoinf(ft_strjoin(me->s1, me->split[i]), me->str + 1, 1); second = calc_expand_esc(me->esc, ft_strlen(me->s1), - ft_strlen(me->split[i]), + (int[2]){ft_strlen(me->split[i]), 0}, (int[2]){me->str - CH(*me->wk)[0], ft_strlen(me->str + 1)}); modify_esc_split(second, me->m_esc[i], ft_strlen(me->s1), ft_strlen(me->split[i])); - my_new = gen_tab(first, second, 0); - ft_ld_pushfront(&wk_tmp, my_new); + my_new = gen_tab(first, second, NULL, 0); + ft_ld_pushfront(me->wk, my_new); } me->wk = &wk_tmp; } -static void init_expand(t_expand *me, char *start) +static int init_expand(t_expand *me, char *start) { unsigned char *esc; @@ -81,30 +90,34 @@ static void init_expand(t_expand *me, char *start) ft_strdel(&me->s1); ft_tabdel(&me->split); ft_tabdel((char ***)&me->m_esc); + return (1); } static int search_brace(t_expand *me) { char *start; + int com; int nb; start = NULL; nb = 0; - while (*me->str) + com = 0; + while (*++me->str) { - start = *me->str == '{' - && !is_char_esc(me->esc, CH(*me->wk)[0], me->str) - && nb == 0 ? me->str : start; - nb += *me->str == '{' - && !is_char_esc(me->esc, CH(*me->wk)[0], me->str); - nb -= *me->str == '}' - && !is_char_esc(me->esc, CH(*me->wk)[0], me->str); + start = *me->str == '{' && !is_char_esc(me->esc, CH(*me->wk)[0], + me->str) && nb == 0 ? me->str : start; + nb += *me->str == '{' && !is_char_esc(me->esc, CH(*me->wk)[0], me->str); + nb -= *me->str == '}' && !is_char_esc(me->esc, CH(*me->wk)[0], me->str); + com += *me->str == ',' && !is_char_esc(me->esc, CH(*me->wk)[0], me->str) + && nb == 1; if (!nb && start) { - init_expand(me, start); - return (1); + if (com) + return (init_expand(me, start)); + set_char_esc(me->esc, CH(*me->wk)[0], start); + set_char_esc(me->esc, CH(*me->wk)[0], me->str); + return (2); } - ++me->str; } return (0); } @@ -115,23 +128,22 @@ void expand_brace(t_glob *gl) int do_it; t_expand me; - ft_ld_pushfront(&gl->m_pat, gen_tab("", (const unsigned char *)"", 1)); - ft_ld_pushfront(&gl->m_pat, gen_tab(gl->pat, gl->esc, 1)); me = (t_expand){NULL, NULL, NULL, NULL, NULL, NULL}; do_it = 1; while (do_it) { do_it = 0; - while (gl->m_pat->next && !do_it) + while (gl->m_pat && !do_it) { me.wk = &gl->m_pat; me.esc = UCH(gl->m_pat)[1]; me.str = CH(gl->m_pat)[0]; - if ((tmp = gl->m_pat) && search_brace(&me)) - { + --me.str; + if ((tmp = gl->m_pat) && + (do_it = search_brace(&me)) == 1) ft_ld_del(&tmp, &ft_tabdel); - do_it = 1; - } + if (!gl->m_pat->next) + break ; gl->m_pat = gl->m_pat->next; } gl->m_pat = ft_ld_front(gl->m_pat); diff --git a/42sh/src/glob/expand_esc.c b/42sh/src/glob/expand_esc.c index 9ad603e4..35777c6f 100644 --- a/42sh/src/glob/expand_esc.c +++ b/42sh/src/glob/expand_esc.c @@ -6,37 +6,37 @@ /* By: wescande +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2017/01/31 23:18:56 by wescande #+# #+# */ -/* Updated: 2017/01/31 23:19:45 by wescande ### ########.fr */ +/* Updated: 2017/02/20 17:25:43 by wescande ### ########.fr */ /* */ /* ************************************************************************** */ #include "glob.h" unsigned char *calc_expand_esc(const unsigned char *esc, - int nb_start, int nb_middle, int *nb_end) + int nb_start, int *nb_middle, int *nb_end) { unsigned char *new_esc; int index; int pos; - if (!(new_esc = (unsigned char *)ft_strnew(((nb_start + nb_middle - + nb_end[1]) / 8) + 1))) + if (!(new_esc = (unsigned char *)ft_strnew(((nb_start + nb_middle[0] + + nb_end[1]) >> 3) + 1))) return (NULL); index = -1; while (++index < nb_start) - new_esc[index / 8] |= - ((esc[index / 8] >> (7 - index % 8)) & 1) << (7 - index % 8); + new_esc[index >> 3] |= + ((esc[index >> 3] >> (7 - index % 8)) & 1) << (7 - index % 8); pos = -1; - while (++pos < nb_middle) + while (++pos < nb_middle[0]) { - new_esc[index / 8] |= 0 << (7 - index % 8); + new_esc[index >> 3] |= nb_middle[1] << (7 - index % 8); ++index; } pos = nb_end[0]; while (++pos <= nb_end[0] + nb_end[1]) { - new_esc[index / 8] |= - ((esc[pos / 8] >> (7 - pos % 8)) & 1) << (7 - index % 8); + new_esc[index >> 3] |= + ((esc[pos >> 3] >> (7 - pos % 8)) & 1) << (7 - index % 8); ++index; } return (new_esc); @@ -52,8 +52,8 @@ void modify_esc_split(unsigned char *esc_dest, while (++index < len) { wk = index + start - 1; - esc_dest[wk / 8] |= - ((esc_src[index / 8] >> (7 - index % 8)) & 1) << (7 - wk % 8); + esc_dest[wk >> 3] |= + ((esc_src[index >> 3] >> (7 - index % 8)) & 1) << (7 - wk % 8); } } @@ -63,13 +63,13 @@ unsigned char *ft_sub_esc(const unsigned char *esc, unsigned char *new_esc; int index; - if (!(new_esc = (unsigned char *)ft_strnew(((len) / 8) + 1))) + if (!(new_esc = (unsigned char *)ft_strnew(((len) >> 3) + 1))) return (NULL); index = -1; while (++index < len) { - new_esc[index / 8] |= - ((esc[start / 8] >> (7 - start % 8)) & 1) << (7 - index % 8); + new_esc[index >> 3] |= + ((esc[start >> 3] >> (7 - start % 8)) & 1) << (7 - index % 8); ++start; } return (new_esc); diff --git a/42sh/src/glob/expand_var.c b/42sh/src/glob/expand_var.c new file mode 100644 index 00000000..bcf85bc9 --- /dev/null +++ b/42sh/src/glob/expand_var.c @@ -0,0 +1,85 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* expand_var.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/06 16:09:27 by wescande #+# #+# */ +/* Updated: 2017/02/20 18:56:50 by wescande ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "glob.h" + +/* +** expand_var return value of $var in the string. +** input parameters are : +** -t_glob *gl -> struct of expanding +*/ + +static void insert_var(t_glob *gl, char *pos, char *name, char *content) +{ + char *s1; + char *s2; + int delta; + unsigned char *new_esc; + + delta = pos - gl->pat; + s1 = ft_strsub(gl->pat, 0, delta); + delta += ft_strlen(name) + 1; + s2 = ft_strsubf(gl->pat, delta, ft_strlen(gl->pat) - delta, 1); + gl->pat = ft_strjoinf(ft_strjoin(s1, content), s2, 1); + new_esc = calc_expand_esc(gl->esc, ft_strlen(s1), + (int[2]){ft_strlen(content), 1}, + (int[2]){delta, ft_strlen(s2)}); + ft_memdel((void **)&gl->esc); + gl->esc = new_esc; + new_esc = calc_expand_esc(gl->esc2, ft_strlen(s1), + (int[2]){ft_strlen(content), 1}, + (int[2]){delta, ft_strlen(s2)}); + ft_memdel((void **)&gl->esc2); + gl->esc2 = new_esc; + ft_strdel(&s1); + ft_strdel(&s2); + ft_strdel(&content); +} + +static char *get_name(t_glob *gl, const char *pat) +{ + const char *str; + + str = pat; + if (ft_isdigit(*str)) + return (ft_strsub(pat, 0, str - pat + 1)); + if (*str == '?') + return (ft_strsub(pat, 0, str - pat + 1)); + while ((ft_isalnum(*str) || *str == '_' || *str == '-') + && !is_char_esc(gl->esc2, gl->pat, str)) + ++str; + return (ft_strsub(pat, 0, str - pat)); +} + +void expand_var(t_glob *gl) +{ + char *pat; + char *var; + char *content; + + pat = gl->pat; + while (*pat) + { + if (*pat == '$' && !is_char_esc(gl->esc2, gl->pat, pat) && + (var = get_name(gl, pat + 1))) + { + if (var && *var) + { + content = ft_getenv(data_singleton()->env, var); + insert_var(gl, pat, var, content); + pat = gl->pat; + } + ft_strdel(&var); + } + ++pat; + } +} diff --git a/42sh/src/glob/ft_strsplit_spe.c b/42sh/src/glob/ft_strsplit_spe.c index a76d475e..8c11de67 100644 --- a/42sh/src/glob/ft_strsplit_spe.c +++ b/42sh/src/glob/ft_strsplit_spe.c @@ -6,7 +6,7 @@ /* By: wescande +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2017/01/31 20:49:30 by wescande #+# #+# */ -/* Updated: 2017/01/31 23:15:41 by wescande ### ########.fr */ +/* Updated: 2017/02/20 18:57:58 by wescande ### ########.fr */ /* */ /* ************************************************************************** */ @@ -63,9 +63,8 @@ char **ft_strsplit_spe(const char *str, const char *fix; int len; - if (!str) - return (NULL); - if (!(s1 = (char**)malloc(sizeof(*s1) * (ft_nbstr_c(str, esc, c) + 1)))) + if (!str || !(s1 = + (char**)malloc(sizeof(*s1) * (ft_nbstr_c(str, esc, c) + 1)))) return (NULL); i = 0; fix = str; @@ -76,6 +75,7 @@ char **ft_strsplit_spe(const char *str, if (!(s1[i] = (char*)malloc(sizeof(**s1) * (len + 1)))) return (NULL); ft_strncpy(s1[i], str, len); + s1[i][len] = '\0'; str = str + len; ++i; while (*str && *str == c) diff --git a/42sh/src/glob/glob.c b/42sh/src/glob/glob.c index 1ec41786..d5832efd 100644 --- a/42sh/src/glob/glob.c +++ b/42sh/src/glob/glob.c @@ -6,7 +6,7 @@ /* By: wescande +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2017/01/04 16:29:54 by wescande #+# #+# */ -/* Updated: 2017/02/01 19:46:22 by wescande ### ########.fr */ +/* Updated: 2017/02/20 19:04:44 by wescande ### ########.fr */ /* */ /* ************************************************************************** */ @@ -22,37 +22,44 @@ ** to just expanse in local directory and not in path dir */ -static char **treat_glob(t_ld **match) +static char **treat_glob(t_glob *gl) { - char **gl; + char **ret; - gl = NULL; - ft_ld_reverse(match); - gl = ft_ld_to_tab(*match); - ft_ld_clear(match, &ft_strdel); - return (gl); + ret= NULL; + ft_ld_clear(&gl->m_pat, &ft_tabdel); + ft_ld_reverse(&gl->match); + ret = ft_ld_to_tab(gl->match); + ft_ld_clear(&gl->match, &ft_strdel); + return (ret); } -char **glob(const char *pat, const unsigned char *esc) +char **glob(char *pat, unsigned char *esc, + unsigned char *esc2) { t_glob gl; - int ret; + int len; - gl = (t_glob){pat, esc, NULL, NULL}; + len = ft_strlen(pat); + gl = (t_glob){0, 0, ft_strdup(pat), dup_char_esc(esc, (len >> 3) + 1), + dup_char_esc(esc2, (len >> 3) + 1), NULL, NULL}; + expand_var(&gl); + expand_bquote(&gl); expand_brace(&gl); - while (gl.m_pat->next) + while (gl.m_pat && !(gl.found = 0)) { - gl.pat = ((char **)gl.m_pat->content)[0]; - gl.esc = ((unsigned char **)gl.m_pat->content)[1]; - if (gl.pat[0] != '/') - ret = dir_research(&gl, ".", gl.pat, 0); + gl.cur_dir = 1; + gl.pat = CH(gl.m_pat)[0]; + if ((gl.esc = UCH(gl.m_pat)[1]) && gl.pat[0] != '/') + dir_research(&gl, ".", gl.pat, 0); else - ret = dir_research(&gl, "/", gl.pat + 1, 0); - if (!ret) + dir_research(&gl, "/", gl.pat + 1, 0); + if (!gl.found) ft_ld_pushfront(&gl.match, - ft_strdup(((char **)gl.m_pat->content)[0])); + ft_strjoin(gl.cur_dir ? "" : "./", CH(gl.m_pat)[0])); + if (!gl.m_pat->next) + break ; gl.m_pat = gl.m_pat->next; } - ft_ld_clear(&gl.m_pat, &ft_tabdel); - return (treat_glob(&gl.match)); + return (treat_glob(&gl)); } diff --git a/42sh/src/glob/is_char_esc.c b/42sh/src/glob/is_char_esc.c index 4ec6f5ae..13061165 100644 --- a/42sh/src/glob/is_char_esc.c +++ b/42sh/src/glob/is_char_esc.c @@ -6,19 +6,66 @@ /* By: wescande +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2017/01/27 18:19:55 by wescande #+# #+# */ -/* Updated: 2017/02/03 14:38:37 by ariard ### ########.fr */ +/* Updated: 2017/02/20 20:43:38 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ #include "glob.h" -int is_char_esc(const unsigned char *esc, +int is_char_esc(const unsigned char *esc, const char *ini_str, const char *str_pos) { int pos; + if (!esc || !ini_str || !str_pos) + return (-1); pos = str_pos - ini_str; - if ((esc[pos / 8] >> (7 - pos % 8)) & 1) + if (pos < 0) + return (-1); + if ((esc[pos >> 3] >> (7 - pos % 8)) & 1) return (1); return (0); } + +void set_char_esc_mode(unsigned char *esc, + const char *ini_str, const char *str_pos, int mode) +{ + int pos; + + if (!esc || !ini_str || !str_pos || mode < 0 || mode > 1) + return ; + pos = str_pos - ini_str; + esc[pos >> 3] |= mode << (7 - pos % 8); +} + +void set_char_esc(unsigned char *esc, + const char *ini_str, const char *str_pos) +{ + int pos; + + if (!esc || !ini_str || !str_pos) + return ; + pos = str_pos - ini_str; + esc[pos >> 3] |= 1 << (7 - pos % 8); +} + +void set_char_no_esc(unsigned char *esc, + const char *ini_str, const char *str_pos) +{ + int pos; + + if (!esc || !ini_str || !str_pos) + return ; + pos = str_pos - ini_str; + esc[pos >> 3] |= 0 << (7 - pos % 8); +} + +unsigned char *dup_char_esc(const unsigned char *esc, const int size) +{ + unsigned char *new_esc; + + if (!(new_esc = (unsigned char *)ft_strnew(size))) + return (NULL); + ft_memcpy(new_esc, esc, size); + return (new_esc); +} diff --git a/42sh/src/glob/lib_perso/ft_memrealloc.c b/42sh/src/glob/lib_perso/ft_memrealloc.c new file mode 100644 index 00000000..2ea59d78 --- /dev/null +++ b/42sh/src/glob/lib_perso/ft_memrealloc.c @@ -0,0 +1,30 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_memrealloc.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/05 13:44:36 by wescande #+# #+# */ +/* Updated: 2017/02/09 17:01:01 by wescande ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "glob.h" + +void *ft_memrealloc(void *ptr, size_t old_s, size_t new_s) +{ + void *n_ptr; + + if (!ptr) + return (ft_memalloc(new_s)); + if (!old_s) + { + ft_memdel(&ptr); + return (ft_memalloc(new_s)); + } + n_ptr = ft_memalloc(new_s); + ft_memcpy(n_ptr, ptr, old_s); + ft_memdel(&ptr); + return (n_ptr); +} diff --git a/42sh/includes/get_next_line.h b/42sh/src/glob/lib_perso/ft_strsubf.c similarity index 55% rename from 42sh/includes/get_next_line.h rename to 42sh/src/glob/lib_perso/ft_strsubf.c index b63d0ac2..2e6d5b51 100644 --- a/42sh/includes/get_next_line.h +++ b/42sh/src/glob/lib_perso/ft_strsubf.c @@ -1,31 +1,25 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* get_next_line.h :+: :+: :+: */ +/* ft_strsubf.c :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: jhalford +#+ +:+ +#+ */ +/* By: wescande +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ -/* Created: 2016/11/05 12:21:36 by jhalford #+# #+# */ -/* Updated: 2016/12/15 13:07:58 by jhalford ### ########.fr */ +/* Created: 2016/11/15 17:20:08 by wescande #+# #+# */ +/* Updated: 2017/02/07 13:01:55 by wescande ### ########.fr */ /* */ /* ************************************************************************** */ -#ifndef GET_NEXT_LINE_H -# define GET_NEXT_LINE_H -# define BUFF_SIZE 32 +#include "glob.h" -# include "libft.h" -# include -# include - -typedef struct s_save t_save; - -struct s_save +char *ft_strsubf(char *s, unsigned int start, size_t len, short int mode) { - int fd; - char *str; -}; + char *sptr; -int get_next_line(int const fd, char **line); - -#endif + if (!s) + return (NULL); + sptr = ft_strsub(s, start, len); + if (mode == 1) + ft_strdel(&s); + return (sptr); +} diff --git a/42sh/src/glob/match_pattern.c b/42sh/src/glob/match_pattern.c index b2688603..536cb08c 100644 --- a/42sh/src/glob/match_pattern.c +++ b/42sh/src/glob/match_pattern.c @@ -6,7 +6,7 @@ /* By: wescande +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2017/01/24 17:30:23 by wescande #+# #+# */ -/* Updated: 2017/02/01 19:46:43 by wescande ### ########.fr */ +/* Updated: 2017/02/20 14:00:41 by wescande ### ########.fr */ /* */ /* ************************************************************************** */ @@ -73,7 +73,7 @@ static int match_star(t_glob *gl, char *str, char *full_word) if (gl->pat[1] == '*' && !is_char_esc(gl->esc, ((char **)gl->m_pat->content)[0], gl->pat + 1)) dir_research(gl, full_word, gl->pat + 1, 1); - if (!*++gl->pat) + if (!*gl->pat || (*gl->pat == '*' && !*++gl->pat)) return (1); fix = str + ft_strlen(str); while (fix > str) @@ -85,17 +85,20 @@ static int match_star(t_glob *gl, char *str, char *full_word) return (0); } -const char *manage_pat(const char *pat, char *str) +static char *manage_pat(t_glob *gl, char *pat, char *str) { if (pat[0] == '.' && pat[1] == '/' && ((str[0] == '.' && str[1] != '/') || str[0] != '.')) + { + gl->cur_dir = 0; return (pat + 2); + } return (pat); } int match_pattern(t_glob *gl, char *str, char *full_word) { - gl->pat = manage_pat(gl->pat, str); + gl->pat = manage_pat(gl, gl->pat, str); while (*gl->pat) { if (is_char_esc(gl->esc, ((char **)gl->m_pat->content)[0], gl->pat)) @@ -104,7 +107,7 @@ int match_pattern(t_glob *gl, char *str, char *full_word) return (0); } else if (*gl->pat == '?') - str++; + ; else if (*gl->pat == '[') { if (!match_bracket(gl, *str)) diff --git a/42sh/src/hash_table/ft_add_hash.c b/42sh/src/hash_table/ft_add_hash.c new file mode 100644 index 00000000..ba18cc91 --- /dev/null +++ b/42sh/src/hash_table/ft_add_hash.c @@ -0,0 +1,28 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_add_hash.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/18 11:20:11 by gwojda #+# #+# */ +/* Updated: 2017/02/18 14:38:21 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +# include "minishell.h" + +int ft_add_hash(t_process *p) +{ + int id; + t_hash hash; + + if (!(hash.path = ft_findexec( + ft_getenv(data_singleton()->env, "PATH"), p->av[0]))) + return (0); + hash.key = ft_strdup(p->av[0]); + id = ft_hash_str(p->av[0]); + ft_lsteadd(&(g_hash[id]), ft_lstnew(&hash, sizeof(t_hash))); + p->path = ft_strdup(hash.path); + return (1); +} diff --git a/42sh/src/hash_table/hash.c b/42sh/src/hash_table/hash.c new file mode 100644 index 00000000..fa3604fd --- /dev/null +++ b/42sh/src/hash_table/hash.c @@ -0,0 +1,23 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* hash.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/18 11:06:19 by gwojda #+# #+# */ +/* Updated: 2017/02/18 14:16:35 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +t_list *g_hash[MAX_HASH] = {NULL}; + +int ft_hash(t_process *p) +{ + if (!ft_is_hash(p)) + if (!ft_add_hash(p)) + return (0); + return (1); +} diff --git a/42sh/src/hash_table/hash_free.c b/42sh/src/hash_table/hash_free.c new file mode 100644 index 00000000..8406c5c3 --- /dev/null +++ b/42sh/src/hash_table/hash_free.c @@ -0,0 +1,34 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* hash_free.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/18 14:12:22 by gwojda #+# #+# */ +/* Updated: 2017/02/18 14:20:20 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void ft_hash_free(void *ptr, size_t size) +{ + (void)size; + free(((t_hash *)ptr)->key); + free(((t_hash *)ptr)->path); + free(ptr); +} + +void ft_free_hash_table(void) +{ + int i; + + i = 0; + while (i < MAX_HASH) + { + if (g_hash[i]) + ft_lstdel(&g_hash[i], &ft_hash_free); + ++i; + } +} diff --git a/42sh/src/hash_table/hash_str.c b/42sh/src/hash_table/hash_str.c new file mode 100644 index 00000000..f7e70f11 --- /dev/null +++ b/42sh/src/hash_table/hash_str.c @@ -0,0 +1,34 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* hash_str.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/18 11:32:18 by gwojda #+# #+# */ +/* Updated: 2017/02/19 12:58:47 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int ft_hash_str(char *str) +{ + int i; + int id; + + i = 0; + id = 0; + while (str[i]) + { + id += str[i] * ft_pow(10, i); + id = id % MAX_HASH; + ++i; + } + if (id < 0) + { + id *= -1; + id = id % MAX_HASH; + } + return (id); +} diff --git a/42sh/src/hash_table/is_hash.c b/42sh/src/hash_table/is_hash.c new file mode 100644 index 00000000..03fdf717 --- /dev/null +++ b/42sh/src/hash_table/is_hash.c @@ -0,0 +1,41 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* is_hash.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/18 11:08:40 by gwojda #+# #+# */ +/* Updated: 2017/02/18 16:42:12 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int ft_is_hash(t_process *p) +{ + t_list *list; + t_list *ref; + int id; + + id = ft_hash_str(p->av[0]); + list = g_hash[id]; + ref = list; + while (list) + { + if (!ft_strcmp(((t_hash *)list->content)->key, p->av[0])) + { + if (access(((t_hash *)list->content)->path, X_OK)) + { + ref->next = list->next; + ft_lstdelone(&list, &ft_hash_free); + return (0); + } + p->path = ft_strdup(((t_hash *)list->content)->path); + return (1); + } + ref = list; + list = list->next; + } + return (0); +} diff --git a/42sh/src/history/add_str_in_history.c b/42sh/src/history/add_str_in_history.c new file mode 100644 index 00000000..a0b37c4a --- /dev/null +++ b/42sh/src/history/add_str_in_history.c @@ -0,0 +1,42 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* add_str_in_history.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/14 11:27:03 by gwojda #+# #+# */ +/* Updated: 2017/02/16 12:37:35 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void ft_add_in_history_file(char *str) +{ + int fd; + char *home; + char *path; + + if (!(home = ft_getenv(data_singleton()->env, "HOME"))) + return ; + path = ft_str3join(home, "/", ".42sh_history"); + fd = open(path, O_CREAT | O_WRONLY | O_APPEND, S_IWUSR | S_IRUSR); + if (fd == -1) + return ; + write(fd, str, ft_strlen(str)); + write(fd, "\n", 1); + free(path); + close(fd); +} + +void ft_add_str_in_history(char *str) +{ + if (str && (!data_singleton()->line.list_beg || + ft_strcmp(data_singleton()->line.list_beg->prev->str, str))) + { + ft_push_back_history(&data_singleton()->line.list_beg, + ft_create_history_list(str)); + ft_add_in_history_file(str); + } +} diff --git a/42sh/src/history/history.c b/42sh/src/history/history.c new file mode 100644 index 00000000..5464edc3 --- /dev/null +++ b/42sh/src/history/history.c @@ -0,0 +1,74 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* history.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/02 15:22:19 by gwojda #+# #+# */ +/* Updated: 2017/02/16 16:12:59 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static void ft_clear_before_history(char **str) +{ + if (*str) + { + if (POS) + { + --POS; + ft_get_beggin_with_curs(*str, &POS); + } + ft_puttermcaps("cd"); + POS = 0; + ft_strdel(str); + } +} + +void ft_history_down(void) +{ + t_list_history *head; + + head = data_singleton()->line.list_cur; + if (!head) + return ; + ft_clear_before_history(&STR); + if (head->next) + head = head->next; + if (!head->str) + STR = NULL; + else + STR = ft_strdup(head->str); + if (STR) + ft_current_str(STR, POS); + if (STR) + POS = ft_strlen_next(STR, POS); + else + POS = 0; + data_singleton()->line.list_cur = head; +} + +void ft_history_up(void) +{ + t_list_history *head; + + head = data_singleton()->line.list_cur; + if (!head) + return ; + ft_clear_before_history(&STR); + if (head->prev) + head = head->prev; + if (!head->str) + STR = NULL; + else + STR = ft_strdup(head->str); + if (STR) + ft_current_str(STR, POS); + if (STR) + POS = ft_strlen_next(STR, POS); + else + POS = 0; + data_singleton()->line.list_cur = head; +} diff --git a/42sh/src/history/history_parsing.c b/42sh/src/history/history_parsing.c new file mode 100644 index 00000000..d2ec5ae2 --- /dev/null +++ b/42sh/src/history/history_parsing.c @@ -0,0 +1,95 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* history_parsing.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/25 11:39:47 by gwojda #+# #+# */ +/* Updated: 2017/02/16 12:28:52 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static int ft_history_parsing_4(char *str, int *i) +{ + int tmp; + + if (!ft_strncmp("!!", str + *i, 2)) + { + ft_realloc_str_history(&(data_singleton()->line.input), *i, 0, 2); + ++(*i); + return (1); + } + else if (ft_isdigit(str[(*i) + 1])) + { + tmp = ft_nbr_len(ft_atoi(str + *i + 1)); + ft_realloc_str_history(&(data_singleton()->line.input), *i, + ft_atoi(str + (*i) + 1), ft_nbr_len(ft_atoi(str + *i + 1)) + 1); + (*i) += tmp; + return (1); + } + return (0); +} + +static int ft_history_parsing_3(char *str, int *i) +{ + int tmp; + + if (ft_history_parsing_4(str, i)) + return (1); + else if (str[*i + 1] == '-' && ft_isdigit(str[*i + 2])) + { + tmp = ft_nbr_len(ft_atoi(str + *i + 2)); + ft_realloc_str_history(&(data_singleton()->line.input), *i, + data_singleton()->line.list_size - ft_atoi(str + *i + 2), + ft_nbr_len(ft_atoi(str + *i + 2)) + 2); + i += tmp; + } + else if (str[*i + 1] == '?') + ft_realloc_str_history_3(&(data_singleton()->line.input), *i, + ft_strdupi_w(str + *i + 2)); + else if (str[*i + 1] != ' ') + ft_realloc_str_history_2(&(data_singleton()->line.input), *i, + ft_strdupi_w(str + *i + 1)); + else + return (0); + return (1); +} + +static void ft_history_parsing_2(void) +{ + data_singleton()->line.pos = 0; + data_singleton()->line.opt = data_singleton()->line.opt | HIST; + ft_prompt(); + data_singleton()->line.input = ft_read_stdin(); + ft_putchar('\n'); + data_singleton()->line.opt = data_singleton()->line.opt | ~HIST; + ft_history_parsing(); +} + +char *ft_history_parsing(void) +{ + int i; + char boolean; + + i = 0; + boolean = 0; + if (!STR) + return (STR); + while (STR && STR[i]) + { + if (STR[i] == '!') + { + boolean = 1; + if (!ft_history_parsing_3(STR, &i)) + boolean = 0; + } + STR = data_singleton()->line.input; + ++i; + } + if (boolean) + ft_history_parsing_2(); + return (STR); +} diff --git a/42sh/src/history/history_parsing_toolz.c b/42sh/src/history/history_parsing_toolz.c new file mode 100644 index 00000000..ef10163e --- /dev/null +++ b/42sh/src/history/history_parsing_toolz.c @@ -0,0 +1,93 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* history_parsing_toolz.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/25 14:09:39 by gwojda #+# #+# */ +/* Updated: 2017/02/19 11:55:44 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static char *ft_nget_histo(size_t nb_his) +{ + t_list_history *list; + size_t i; + + i = 0; + list = data_singleton()->line.list_beg; + if (!list) + return (NULL); + if (!list->str) + list = list->prev; + while (i < nb_his && list->str) + { + list = list->prev; + ++i; + } + return (list->str); +} + +void ft_realloc_str_history(char **str, size_t pos, int nb_his, int len) +{ + char *new_str; + char *new_str2; + char *new_str3; + + if (!*str) + return ; + new_str = ft_strndup(*str, pos); + new_str3 = ft_nget_histo(nb_his); + if (new_str3) + { + new_str2 = ft_strjoin(new_str, new_str3); + new_str3 = ft_strjoin(new_str2, (*str) + pos + len); + free(new_str2); + } + else + new_str3 = ft_strjoin(new_str, (*str) + pos + len); + free(new_str); + free(*str); + *str = new_str3; +} + +static char *ft_strget_histo(char *str) +{ + t_list_history *list; + + list = data_singleton()->line.list_beg; + if (!list) + return (NULL); + if (!list->str) + list = list->prev; + while (list->str && ft_strncmp(list->str, str, ft_strlen(str))) + list = list->prev; + return (list->str); +} + +void ft_realloc_str_history_2(char **str, size_t pos, char *s) +{ + char *new_str; + char *new_str2; + char *new_str3; + + if (!*str) + return ; + new_str = ft_strndup(*str, pos); + new_str3 = ft_strget_histo(s); + if (new_str3) + { + new_str2 = ft_strjoin(new_str, new_str3); + new_str3 = ft_strjoin(new_str2, (*str) + pos + ft_strlen(s) + 1); + free(new_str2); + } + else + new_str3 = ft_strjoin(new_str, (*str) + pos + ft_strlen(s) + 1); + free(new_str); + free(s); + free(*str); + *str = new_str3; +} diff --git a/42sh/src/history/history_parsing_toolz_2.c b/42sh/src/history/history_parsing_toolz_2.c new file mode 100644 index 00000000..23ce77ae --- /dev/null +++ b/42sh/src/history/history_parsing_toolz_2.c @@ -0,0 +1,64 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* history_parsing_toolz_2.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/25 20:04:16 by gwojda #+# #+# */ +/* Updated: 2017/01/26 11:33:22 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +char *ft_strget_history(char *str) +{ + t_list_history *list; + size_t i; + char *tmp; + + list = data_singleton()->line.list_beg; + if (!list) + return (NULL); + if (!list->str) + list = list->prev; + while (list->str) + { + tmp = list->str; + i = 0; + while (tmp[i]) + { + if (ft_strlen(tmp + i) >= ft_strlen(str) + && !ft_strncmp(tmp + i, str, ft_strlen(str))) + return (tmp); + ++i; + } + list = list->prev; + } + return (list->str); +} + +void ft_realloc_str_history_3(char **str, size_t pos, char *s) +{ + char *new_str; + char *new_str2; + char *new_str3; + + if (!*str) + return ; + new_str = ft_strndup(*str, pos); + new_str3 = ft_strget_history(s); + if (new_str3) + { + new_str2 = ft_strjoin(new_str, new_str3); + free(new_str); + new_str3 = ft_strjoin(new_str2, (*str) + pos + ft_strlen(s) + 2); + free(new_str2); + } + else + new_str3 = ft_strjoin(new_str, (*str) + pos + ft_strlen(s) + 2); + free(s); + free(*str); + *str = new_str3; +} diff --git a/42sh/src/history/list_toolz.c b/42sh/src/history/list_toolz.c new file mode 100644 index 00000000..51bde359 --- /dev/null +++ b/42sh/src/history/list_toolz.c @@ -0,0 +1,51 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* list_toolz.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/17 11:37:47 by gwojda #+# #+# */ +/* Updated: 2017/02/02 16:08:01 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +t_list_history *ft_create_history_list(char *str) +{ + t_list_history *list; + + list = (t_list_history *)malloc(sizeof(t_list_history)); + if (!list) + return (NULL); + if (!str) + list->str = NULL; + else + list->str = ft_strdup(str); + list->prev = NULL; + list->next = NULL; + return (list); +} + +void ft_push_back_history(t_list_history **head, t_list_history *new) +{ + ++(data_singleton()->line.list_size); + if (!*head) + { + *head = new; + (*head)->prev = ft_create_history_list(NULL); + (*head)->prev->next = (*head); + (*head)->next = ft_create_history_list(NULL); + (*head)->next->prev = (*head); + (*head) = (*head)->next; + (data_singleton())->line.list_end = new; + return ; + } + while ((*head)->next) + (*head) = (*head)->next; + new->prev = (*head)->prev; + (*head)->prev->next = new; + new->next = (*head); + (*head)->prev = new; +} diff --git a/42sh/src/history/surch_in_history.c b/42sh/src/history/surch_in_history.c new file mode 100644 index 00000000..28360348 --- /dev/null +++ b/42sh/src/history/surch_in_history.c @@ -0,0 +1,92 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* surch_in_history.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/26 10:43:16 by gwojda #+# #+# */ +/* Updated: 2017/02/04 15:50:26 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static void ft_clear_prompt(char *str, size_t *pos, size_t srch_pos) +{ + if (str) + ft_get_beggin_with_curs(str, pos); + else if (*pos) + { + ft_putnc('\b', *pos); + (*pos) = 0; + } + ft_putnc('\b', data_singleton()->line.prompt_size + srch_pos + 1); + ft_puttermcaps("cd"); +} + +static void ft_surch_and_realloc(char **str, char **str_srch, + int ret, size_t *srch_pos) +{ + *str_srch = ft_realloc_imput(*str_srch, ret, *srch_pos); + ++(*srch_pos); + *str = ft_strget_history(*str_srch); +} + +static void ft_give_new_prompt(char *str_srch, size_t srch_pos) +{ + ft_clear_prompt(STR, &POS, srch_pos); + data_singleton()->line.prompt_size = 21; + if (str_srch) + ft_printf("\033[35m(reverse-i-search)`\033[32m%s\033[35m': \033[37m", + str_srch); + else + ft_putstr("\033[35m(reverse-i-search)`': \033[37m"); + if (STR) + { + ft_current_str(STR, POS); + ft_get_next_str(STR, &POS); + } +} + +static void ft_modify_str(char *str_srch, size_t srch_pos) +{ + ft_clear_prompt(STR, &POS, srch_pos); + ft_prompt(); + if (STR) + { + STR = ft_strdup(STR); + ft_current_str(STR, POS); + ft_get_next_str(STR, &POS); + } + free(str_srch); +} + +void ft_surch_in_history(void) +{ + char *str_srch; + int ret; + size_t srch_pos; + + srch_pos = 0; + str_srch = NULL; + if (STR) + ft_strdel(&STR); + while (42) + { + ft_give_new_prompt(str_srch, srch_pos); + ret = 0; + read(0, &ret, sizeof(int)); + if (ft_isprint(ret)) + ft_surch_and_realloc(&STR, &str_srch, ret, &srch_pos); + else if (ret == 127 && srch_pos) + { + --srch_pos; + str_srch = ft_remove_imput(str_srch, srch_pos); + ft_puttermcaps("le"); + } + else if (ret != 127) + break ; + } + ft_modify_str(str_srch, srch_pos); +} diff --git a/42sh/src/job-control/builtin_bg.c b/42sh/src/job-control/builtin_bg.c index a972a19a..f58a1d1e 100644 --- a/42sh/src/job-control/builtin_bg.c +++ b/42sh/src/job-control/builtin_bg.c @@ -21,9 +21,9 @@ int builtin_bg(const char *path, char *const av[], char *const envp[]) (void)path; (void)envp; - if (!SHELL_HAS_JOBC(data_singleton()->opts)) + if (!SH_HAS_JOBC(data_singleton()->opts)) { - ft_dprintf(2, "{red}bg: %s{eoc}\n", SHELL_MSG_NOJOBC); + ft_dprintf(2, "{red}bg: %s{eoc}\n", SH_MSG_NOJOBC); return (-1); } jobc = &data_singleton()->jobc; diff --git a/42sh/src/job-control/builtin_fg.c b/42sh/src/job-control/builtin_fg.c index 48945eca..373ba8a9 100644 --- a/42sh/src/job-control/builtin_fg.c +++ b/42sh/src/job-control/builtin_fg.c @@ -21,9 +21,9 @@ int builtin_fg(const char *path, char *const av[], char *const envp[]) (void)path; (void)envp; - if (!SHELL_HAS_JOBC(data_singleton()->opts)) + if (!SH_HAS_JOBC(data_singleton()->opts)) { - ft_dprintf(2, "{red}fg: %s{eoc}\n", SHELL_MSG_NOJOBC); + ft_dprintf(2, "{red}fg: %s{eoc}\n", SH_MSG_NOJOBC); return (-1); } jobc = &data_singleton()->jobc; diff --git a/42sh/src/job-control/builtin_jobs.c b/42sh/src/job-control/builtin_jobs.c index 9e3fe05d..f2a83ee0 100644 --- a/42sh/src/job-control/builtin_jobs.c +++ b/42sh/src/job-control/builtin_jobs.c @@ -90,9 +90,9 @@ int builtin_jobs(const char *path, char *const av[], char *const envp[]) (void)path; (void)envp; - if (!SHELL_HAS_JOBC(data_singleton()->opts)) + if (!SH_HAS_JOBC(data_singleton()->opts)) { - ft_dprintf(2, "{red}jobs: %s{eoc}\n", SHELL_MSG_NOJOBC); + ft_dprintf(2, "{red}jobs: %s{eoc}\n", SH_MSG_NOJOBC); return (1); } if ((opts = bt_jobs_parse((char**)av, &i)) < 0) diff --git a/42sh/src/job-control/do_job_notification.c b/42sh/src/job-control/do_job_notification.c index b47b83b0..74eff978 100644 --- a/42sh/src/job-control/do_job_notification.c +++ b/42sh/src/job-control/do_job_notification.c @@ -6,7 +6,7 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/12/15 13:01:19 by jhalford #+# #+# */ -/* Updated: 2017/01/31 15:06:05 by jhalford ### ########.fr */ +/* Updated: 2017/02/03 15:47:44 by jhalford ### ########.fr */ /* */ /* ************************************************************************** */ diff --git a/42sh/src/job-control/job_update_status.c b/42sh/src/job-control/job_update_status.c index e9f9a24e..1fa30cd5 100644 --- a/42sh/src/job-control/job_update_status.c +++ b/42sh/src/job-control/job_update_status.c @@ -6,7 +6,7 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/12/15 12:56:11 by jhalford #+# #+# */ -/* Updated: 2017/01/31 15:07:51 by jhalford ### ########.fr */ +/* Updated: 2017/02/03 15:50:30 by jhalford ### ########.fr */ /* */ /* ************************************************************************** */ diff --git a/42sh/src/job-control/process_free.c b/42sh/src/job-control/process_free.c index f0f77c0a..ce23bf71 100644 --- a/42sh/src/job-control/process_free.c +++ b/42sh/src/job-control/process_free.c @@ -6,7 +6,7 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/12/12 12:41:11 by jhalford #+# #+# */ -/* Updated: 2017/02/02 15:45:25 by jhalford ### ########.fr */ +/* Updated: 2017/02/03 13:59:25 by jhalford ### ########.fr */ /* */ /* ************************************************************************** */ @@ -20,5 +20,6 @@ void process_free(void *content, size_t content_size) p = content; ft_strdel(&p->path); ft_sstrfree(p->av); + ft_lstdel(&p->redirs, ft_lst_cfree); free(p); } diff --git a/42sh/src/job-control/process_mark_status.c b/42sh/src/job-control/process_mark_status.c index e071c53f..fd285c0b 100644 --- a/42sh/src/job-control/process_mark_status.c +++ b/42sh/src/job-control/process_mark_status.c @@ -6,7 +6,7 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/12/12 12:41:11 by jhalford #+# #+# */ -/* Updated: 2017/01/31 15:10:04 by jhalford ### ########.fr */ +/* Updated: 2017/02/03 15:50:29 by jhalford ### ########.fr */ /* */ /* ************************************************************************** */ diff --git a/42sh/src/job-control/sigtstp_handler.c b/42sh/src/job-control/sigtstp_handler.c index 6fd5a311..e6c9b923 100644 --- a/42sh/src/job-control/sigtstp_handler.c +++ b/42sh/src/job-control/sigtstp_handler.c @@ -18,5 +18,6 @@ void sigtstp_handler(int signo) (void)signo; jobc = &data_singleton()->jobc; - DG("got SIGTSTP in process %i", getpid()); + DG("got SIGTSTP pid=%i, pgrp=%i, shell_pgid=%i", getpid(), getpgrp(), data_singleton()->jobc.shell_pgid); + ft_putchar('\x1A'); } diff --git a/42sh/src/lexer/ft_post_tokenize.c b/42sh/src/lexer/ft_post_tokenize.c deleted file mode 100644 index dfb0b406..00000000 --- a/42sh/src/lexer/ft_post_tokenize.c +++ /dev/null @@ -1,43 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* ft_post_tokenize.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: jhalford +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2017/01/11 16:11:11 by jhalford #+# #+# */ -/* Updated: 2017/02/17 17:28:15 by ariard ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "lexer.h" - -int ft_post_tokenize(t_list **alst, char **str) -{ -// int ret; -// t_flag tk; - - (void)str; -// token_print(*alst); - get_reserved_words(alst); -/* while ((ret = reduce_parens(alst, *str))) - if (ret == -1) - { - ft_dprintf(2, "{red}%s: parse error near '('{eoc}\n", SHELL_NAME); - return (-1); - } - tk = TK_PAREN_CLOSE; - if (ft_lst_find(*alst, &tk, token_cmp_type)) - { - ft_dprintf(2, "{red}%s: parse error near ')'{eoc}\n", SHELL_NAME); - return (-1); - } - while ((ret = reduce_bquotes(alst, str))) - if (ret == -1) - { - ft_dprintf(2, "{red}%s: parse error near '`'{eoc}\n", SHELL_NAME); - return (-1); - } - DG("new command from bquotes: '%s'", *str); -*/ return (0); -} diff --git a/42sh/src/lexer/get_lexer_stack.c b/42sh/src/lexer/get_lexer_stack.c new file mode 100644 index 00000000..10ce9b70 --- /dev/null +++ b/42sh/src/lexer/get_lexer_stack.c @@ -0,0 +1,6 @@ +#include "lexer.h" + +int get_lexer_stack(t_lexer lexer) +{ + return (lexer.stack ? *(int*)lexer.stack->content : 0); +} diff --git a/42sh/src/lexer/get_lexer_state.c b/42sh/src/lexer/get_state_global.c similarity index 59% rename from 42sh/src/lexer/get_lexer_state.c rename to 42sh/src/lexer/get_state_global.c index 7bc728f2..41ae160e 100644 --- a/42sh/src/lexer/get_lexer_state.c +++ b/42sh/src/lexer/get_state_global.c @@ -1,34 +1,39 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* get_lexer_state.c :+: :+: :+: */ +/* get_state_global.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ -/* Created: 2017/01/10 13:45:46 by jhalford #+# #+# */ -/* Updated: 2017/02/03 19:53:20 by ariard ### ########.fr */ +/* Created: 2017/02/09 20:39:06 by jhalford #+# #+# */ +/* Updated: 2017/02/20 20:48:53 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ #include "lexer.h" -t_lexstate get_lexer_state(char *str) +t_lexstate get_state_global(t_lexer *lexer) { - if (*str == '\n') - return (NEWLINE); - else if (ft_is_delim(*str)) + char c; + + c = lexer->str[lexer->pos]; + if (ft_is_delim(c)) return (DELIM); - else if (*str == '$') - return (VAR); - else if (*str == '&' || *str == ';' || *str == '|') + else if (c == '#') + return (COMMENT); + else if (c == '&' || c == ';' || c == '|') return (SEP); - else if (*str == '\\') + else if (c == '\\') return (BACKSLASH); - else if (*str == '\'') + else if (c == '\'') return (QUOTE); - else if (*str == '\"') + else if (c == '\"') return (DQUOTE); - else if (*str == '(' || *str == ')' || *str == '`') - return (SPECIAL); + else if (c == '`') + return (BQUOTE); + else if (c == '(' || c == ')') + return (PAREN); + else if (c == 0) + return (END); return (0); } diff --git a/42sh/src/lexer/ft_lexer.c b/42sh/src/lexer/get_state_redir.c similarity index 62% rename from 42sh/src/lexer/ft_lexer.c rename to 42sh/src/lexer/get_state_redir.c index 54c390d0..7b6acd31 100644 --- a/42sh/src/lexer/ft_lexer.c +++ b/42sh/src/lexer/get_state_redir.c @@ -1,28 +1,25 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* ft_lexer.c :+: :+: :+: */ +/* get_state_redir.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ -/* Created: 2017/02/02 15:30:59 by jhalford #+# #+# */ -/* Updated: 2017/02/17 17:28:32 by ariard ### ########.fr */ +/* Created: 2017/02/09 20:37:28 by jhalford #+# #+# */ +/* Updated: 2017/02/09 20:39:11 by jhalford ### ########.fr */ /* */ /* ************************************************************************** */ #include "lexer.h" -int ft_lexer(t_list **alst, char **command) +t_lexstate get_state_redir(t_lexer *lexer) { - int ret; + char c; - ret = 0; - if (!*command) - ret = 1; - else if (ft_tokenize(alst, *command, DEFAULT)) - ret = 1; - else if (ft_post_tokenize(alst, command)) - ret = 1; - ft_strdel(command); - return (ret); + c = lexer->str[lexer->pos]; + if (c == '>') + return (GREAT); + else if (c == '<') + return (LESS); + return (0); } diff --git a/42sh/src/lexer/lexer_backslash.c b/42sh/src/lexer/lexer_backslash.c index a2b5b004..4a8a8e4a 100644 --- a/42sh/src/lexer/lexer_backslash.c +++ b/42sh/src/lexer/lexer_backslash.c @@ -6,18 +6,26 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/12/03 11:56:49 by jhalford #+# #+# */ -/* Updated: 2017/02/03 14:47:51 by ariard ### ########.fr */ +/* Updated: 2017/02/20 20:49:19 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ #include "lexer.h" -int lexer_backslash(t_list **alst, char *str) +int lexer_backslash(t_list **alst, t_lexer *lexer) { t_token *token; token = (*alst)->content; token->type = TK_WORD; - token_append(token, str[1], 1); - return (ft_tokenize(alst, str + 2, WORD)); + lexer->pos++; + lexer->state = WORD; + if (lexer->str[lexer->pos] == 0) + { + push(&lexer->stack, BACKSLASH); + return (0); + } + token_append(token, lexer, 1, 1); + lexer->pos++; + return (lexer_lex(alst, lexer)); } diff --git a/42sh/src/lexer/lexer_bquote.c b/42sh/src/lexer/lexer_bquote.c new file mode 100644 index 00000000..0ffbc04e --- /dev/null +++ b/42sh/src/lexer/lexer_bquote.c @@ -0,0 +1,54 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* lexer_bquote.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/09 22:03:48 by jhalford #+# #+# */ +/* Updated: 2017/02/17 15:36:49 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "lexer.h" + +int lexer_bquote(t_list **alst, t_lexer *lexer) +{ + t_token *token; + int top_state; + + token = (*alst)->content; + token->type = TK_WORD; + if (lexer->state == DQUOTE_BQUOTE) + token_append(token, lexer, 1, 0); + else + token_append(token, lexer, 0, 0); + if (lexer->str[lexer->pos] == '`') + { + lexer->pos++; + if (!(lexer->stack && (*(int*)lexer->stack->content == BQUOTE + || *(int*)lexer->stack->content == DQUOTE_BQUOTE))) + { + push(&lexer->stack, lexer->state); + return (lexer_lex(alst, lexer)); + } + top_state = *(int*)pop(&lexer->stack)->content; + lexer->state = top_state == DQUOTE_BQUOTE ? DQUOTE : DEFAULT; + return (lexer_lex(alst, lexer)); + } + if (lexer->str[lexer->pos] == '\\') + { + lexer->pos++; + if (lexer->str[lexer->pos] == 0) + { + push(&lexer->stack, BACKSLASH); + return (0); + } + else + token_append(token, lexer, 1, 1); + lexer->pos++; + return (lexer_lex(alst,lexer)); + } + lexer->pos++; + return (lexer_lex(alst, lexer)); +} diff --git a/42sh/src/lexer/lexer_comment.c b/42sh/src/lexer/lexer_comment.c index 844bf507..1ae43e79 100644 --- a/42sh/src/lexer/lexer_comment.c +++ b/42sh/src/lexer/lexer_comment.c @@ -3,22 +3,21 @@ /* ::: :::::::: */ /* lexer_comment.c :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: ariard +#+ +:+ +#+ */ +/* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ -/* Created: 2017/01/24 18:22:35 by ariard #+# #+# */ -/* Updated: 2017/01/30 17:22:48 by ariard ### ########.fr */ +/* Created: 2017/02/07 12:15:59 by jhalford #+# #+# */ +/* Updated: 2017/02/20 21:03:53 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ #include "lexer.h" -int lexer_comment(t_list **alst, char *str) +int lexer_comment(t_list **alst, t_lexer *lexer) { t_token *token; - (void)str; token = (*alst)->content; - if (!token->type) - ft_lstdel(alst, &token_free); - return (0); + if (lexer->str[lexer->pos] == '\n') + return (lexer_lex(&(*alst)->next, lexer)); + return (lexer_comment(alst, lexer)); } diff --git a/42sh/src/main/ft_print_all_ast.c b/42sh/src/lexer/lexer_comment.c~HEAD similarity index 62% rename from 42sh/src/main/ft_print_all_ast.c rename to 42sh/src/lexer/lexer_comment.c~HEAD index 55003400..844bf507 100644 --- a/42sh/src/main/ft_print_all_ast.c +++ b/42sh/src/lexer/lexer_comment.c~HEAD @@ -1,30 +1,24 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* ft_print_all_ast.c :+: :+: :+: */ +/* lexer_comment.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: ariard +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ -/* Created: 2017/01/30 19:23:49 by ariard #+# #+# */ -/* Updated: 2017/01/31 22:52:06 by ariard ### ########.fr */ +/* Created: 2017/01/24 18:22:35 by ariard #+# #+# */ +/* Updated: 2017/01/30 17:22:48 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ -#include "minishell.h" +#include "lexer.h" -void ft_print_all_ast(t_list *lst_ast) +int lexer_comment(t_list **alst, char *str) { - t_list *tmp; - t_btree **ast; + t_token *token; - tmp = lst_ast; - while (tmp) - { - if (tmp->content) - { - ast = tmp->content; - btree_print(STDBUG, *ast, &ft_putast); - } - tmp = tmp->next; - } + (void)str; + token = (*alst)->content; + if (!token->type) + ft_lstdel(alst, &token_free); + return (0); } diff --git a/42sh/src/lexer/lexer_default.c b/42sh/src/lexer/lexer_default.c index 13a6d1dc..4d67d8cc 100644 --- a/42sh/src/lexer/lexer_default.c +++ b/42sh/src/lexer/lexer_default.c @@ -6,30 +6,24 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/11/28 18:36:21 by jhalford #+# #+# */ -/* Updated: 2017/02/09 19:26:55 by ariard ### ########.fr */ +/* Updated: 2017/02/20 20:50:30 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ #include "lexer.h" -int lexer_default(t_list **alst, char *str) +int lexer_default(t_list **alst, t_lexer *lexer) { - t_lexstate state; t_token *token; + char c; - if ((state = get_lexer_state(str))) - return (ft_tokenize(alst, str, state)); - if (*str == '>') - return (ft_tokenize(alst, str, GREAT)); - else if (*str == '<') - return (ft_tokenize(alst, str, LESS)); - else if (*str == '#') - return (ft_tokenize(alst, str, COMMENT)); - else if (ft_isdigit(*str)) - state = NUMBER; - else - state = WORD; + c = lexer->str[lexer->pos]; + if ((lexer->state = get_state_global(lexer))) + return (lexer_lex(alst, lexer)); + if ((lexer->state = get_state_redir(lexer))) + return (lexer_lex(alst, lexer)); + lexer->state = ft_isdigit(c) ? NUMBER : WORD; token = (*alst)->content; - token->type = TK_N_WORD; - return (ft_tokenize(alst, str, state)); + token->type = TK_WORD; + return (lexer_lex(alst, lexer)); } diff --git a/42sh/src/lexer/lexer_delim.c b/42sh/src/lexer/lexer_delim.c index f068458f..4c7f4eb7 100644 --- a/42sh/src/lexer/lexer_delim.c +++ b/42sh/src/lexer/lexer_delim.c @@ -6,23 +6,28 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/12/03 11:58:44 by jhalford #+# #+# */ -/* Updated: 2017/02/03 19:53:11 by ariard ### ########.fr */ +/* Updated: 2017/02/20 20:52:10 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ #include "lexer.h" -int lexer_delim(t_list **alst, char *str) +int lexer_delim(t_list **alst, t_lexer *lexer) { t_token *token; token = (*alst)->content; - while (ft_is_delim(*str)) - str++; - if (*(str + 1) == '#') - return (ft_tokenize(alst, str + 1, COMMENT)); - else if (token->type) - return (ft_tokenize(&(*alst)->next, str, DEFAULT)); + while (ft_is_delim(lexer->str[lexer->pos])) + lexer->pos++; + lexer->state = DEFAULT; + if (token->type) + { + return (lexer_lex(&(*alst)->next, lexer)); + } else - return (ft_tokenize(alst, str, DEFAULT)); + { + if (lexer->str[lexer->pos] == 0) + ft_lst_delif(alst, (*alst)->content, &ft_addrcmp, &token_free); + return (lexer_lex(alst, lexer)); + } } diff --git a/42sh/src/lexer/lexer_dless.c b/42sh/src/lexer/lexer_dless.c new file mode 100644 index 00000000..f0e0ee4d --- /dev/null +++ b/42sh/src/lexer/lexer_dless.c @@ -0,0 +1,41 @@ +#include "lexer.h" + +int lexer_dless(t_list **alst, t_lexer *lexer) +{ + t_list *heredoc_lst; + t_token *eof_tok; + t_token *heredoc_tok; + + (void)alst; + (void)lexer; + heredoc_lst = *(t_list**)lexer->heredoc_stack->content; + heredoc_tok = heredoc_lst->content; + if (!(heredoc_lst->next)) + { + ft_dprintf(2, "{red}%s: parse error near `\\n'{eoc}\n", SHELL_NAME); + return (1); + } + eof_tok = heredoc_lst->next->content; + if (!(eof_tok->type == TK_WORD)) + { + ft_dprintf(2, "{red}%s: expected word token after <<{eoc}\n", SHELL_NAME); + return (1); + } + DG("heredoc contains [%s]", heredoc_tok->data); + DG("heredoc ends at [%s]", eof_tok->data); + DG("input is [%s]", lexer->str + lexer->pos); + if (ft_strcmp(eof_tok->data, lexer->str + lexer->pos) == 0) + { + pop(&lexer->stack); + pop(&lexer->heredoc_stack); + while (lexer->str[++lexer->pos]) + ; + ft_strappend(&lexer->str, (char[]){'\n', 0}); + lexer->pos++; + return (0); + } + else + while (lexer->str[lexer->pos]) + token_append_char(heredoc_tok, lexer->str[lexer->pos++], 0, 0); + return (lexer_end(alst, lexer)); +} diff --git a/42sh/src/lexer/lexer_dquote.c b/42sh/src/lexer/lexer_dquote.c index ddc4abae..3c241889 100644 --- a/42sh/src/lexer/lexer_dquote.c +++ b/42sh/src/lexer/lexer_dquote.c @@ -6,26 +6,46 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/11/28 18:36:58 by jhalford #+# #+# */ -/* Updated: 2017/02/03 14:49:00 by ariard ### ########.fr */ +/* Updated: 2017/02/20 20:52:24 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ #include "lexer.h" -int lexer_dquote(t_list **alst, char *str) +int lexer_dquote(t_list **alst, t_lexer *lexer) { t_token *token; token = (*alst)->content; - token->type = TK_DQ_WORD; - str++; - if (*str == '\"') - return (ft_tokenize(alst, str + 1, DEFAULT)); - if (*str == '\\') + token->type = TK_WORD; + if (lexer->str[lexer->pos] == '"') { - token_append(token, *(str + 1), 1); - return (lexer_dquote(alst, str + 1)); + lexer->pos++; + if (!(lexer->stack && *(int*)lexer->stack->content == DQUOTE)) + { + push(&lexer->stack, DQUOTE); + return (lexer_lex(alst, lexer)); + } + lexer->state = WORD; + pop(&lexer->stack); + return (lexer_lex(alst, lexer)); } - token_append(token, *str, 1); - return (lexer_dquote(alst, str)); + if (lexer->str[lexer->pos] == '\\') + { + lexer->pos++; + if (lexer->str[lexer->pos] == 0) + return (0); + else + token_append(token, lexer, 1, 1); + lexer->pos++; + return (lexer_lex(alst,lexer)); + } + else if (lexer->str[lexer->pos] == '`') + { + lexer->state = DQUOTE_BQUOTE; + return (lexer_bquote(alst, lexer)); + } + token_append(token, lexer, 1, 0); + lexer->pos++; + return (lexer_lex(alst, lexer)); } diff --git a/42sh/src/lexer/lexer_end.c b/42sh/src/lexer/lexer_end.c new file mode 100644 index 00000000..2ec70dd2 --- /dev/null +++ b/42sh/src/lexer/lexer_end.c @@ -0,0 +1,27 @@ +#include "lexer.h" + +int lexer_end(t_list **alst, t_lexer *lexer) +{ + t_token *token; + + if ((*alst && (lexer->state == QUOTE + || lexer->state == DQUOTE + || lexer->state == BQUOTE)) + || get_lexer_stack(*lexer) == DLESS) + { + ft_strappend(&lexer->str, (char[]){'\n', 0}); + lexer->pos++; + if (get_lexer_stack(*lexer) == DLESS) + { + token = (*(t_list**)lexer->heredoc_stack->content)->content; + token_append_char(token, '\n', 0, 0); + } + else + { + token = (*alst)->content; + token_append_char(token, '\n', 1, 0); + } + return (0); + } + return (0); +} diff --git a/42sh/src/lexer/lexer_great.c b/42sh/src/lexer/lexer_great.c index 84da01ab..48c1a33b 100644 --- a/42sh/src/lexer/lexer_great.c +++ b/42sh/src/lexer/lexer_great.c @@ -6,33 +6,38 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/12/03 12:06:35 by jhalford #+# #+# */ -/* Updated: 2017/02/04 21:27:10 by ariard ### ########.fr */ +/* Updated: 2017/02/20 20:52:38 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ #include "lexer.h" -int lexer_great(t_list **alst, char *str) +int lexer_great(t_list **alst, t_lexer *lexer) { t_token *token; token = (*alst)->content; - token_append(token, str[0], 0); - if (*(str + 1) == '&') + token_append(token, lexer, 0, 0); + lexer->pos++; + if (lexer->str[lexer->pos] == '&') { token->type = TK_GREATAND; - token_append(token, str[1], 0); - return (lexer_greatand(alst, str + 2)); + token_append(token, lexer, 0, 0); + lexer->pos++; + return (lexer_greatand(alst, lexer)); } - else if (*(str + 1) == '>') + if (lexer->str[lexer->pos] == '>') { token->type = TK_DGREAT; - token_append(token, str[1], 0); - return (ft_tokenize(&(*alst)->next, str + 2, DEFAULT)); + token_append(token, lexer, 0, 0); + lexer->pos++; + lexer->state = DEFAULT; + return (lexer_lex(&(*alst)->next, lexer)); } else { token->type = TK_GREAT; - return (ft_tokenize(&(*alst)->next, str + 1, DEFAULT)); + lexer->state = DEFAULT; + return (lexer_lex(&(*alst)->next, lexer)); } } diff --git a/42sh/src/lexer/lexer_greatand.c b/42sh/src/lexer/lexer_greatand.c index a0268048..350bbec1 100644 --- a/42sh/src/lexer/lexer_greatand.c +++ b/42sh/src/lexer/lexer_greatand.c @@ -6,27 +6,31 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/12/03 11:56:58 by jhalford #+# #+# */ -/* Updated: 2017/02/03 14:49:28 by ariard ### ########.fr */ +/* Updated: 2017/02/20 20:52:49 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ #include "lexer.h" -int lexer_greatand(t_list **alst, char *str) +int lexer_greatand(t_list **alst, t_lexer *lexer) { t_token *token; token = (*alst)->content; token->type = TK_GREATAND; - if (ft_isdigit(*str)) + if (ft_isdigit(lexer->str[lexer->pos])) { - token_append(token, *str, 0); - return (lexer_greatand(alst, str + 1)); + token_append(token, lexer, 0, 0); + lexer->pos++; + return (lexer_greatand(alst, lexer)); } - else if (*str == '-') + else if (lexer->str[lexer->pos] == '-') { - token_append(token, *str, 0); - return (ft_tokenize(&(*alst)->next, str + 1, DEFAULT)); + token_append(token, lexer, 0, 0); + lexer->pos++; + lexer->state = DEFAULT; + return (lexer_lex(&(*alst)->next, lexer)); } - return (ft_tokenize(alst, str, DEFAULT)); + lexer->state = DEFAULT; + return (lexer_lex(alst, lexer)); } diff --git a/42sh/src/lexer/lexer_init.c b/42sh/src/lexer/lexer_init.c new file mode 100644 index 00000000..230ee3f6 --- /dev/null +++ b/42sh/src/lexer/lexer_init.c @@ -0,0 +1,10 @@ +#include "lexer.h" + +void lexer_init(t_lexer *lexer) +{ + lexer->str = NULL; + lexer->pos = 0; + lexer->state = DEFAULT; + lexer->stack = NULL; + lexer->heredoc_stack = NULL; +} diff --git a/42sh/src/lexer/lexer_less.c b/42sh/src/lexer/lexer_less.c index d9e8ea36..241f9ae1 100644 --- a/42sh/src/lexer/lexer_less.c +++ b/42sh/src/lexer/lexer_less.c @@ -6,33 +6,41 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/12/03 12:06:53 by jhalford #+# #+# */ -/* Updated: 2017/02/09 15:00:13 by ariard ### ########.fr */ +/* Updated: 2017/02/20 20:53:06 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ #include "lexer.h" -int lexer_less(t_list **alst, char *str) +int lexer_less(t_list **alst, t_lexer *lexer) { t_token *token; token = (*alst)->content; - token_append(token, str[0], 0); - if (*(str + 1) == '&') + token_append(token, lexer, 0, 0); + lexer->pos++; + if (lexer->str[lexer->pos] == '&') { token->type = TK_LESSAND; - token_append(token, str[1], 0); - return (lexer_lessand(alst, str + 2)); + token_append(token, lexer, 0, 0); + lexer->pos++; + return (lexer_lessand(alst, lexer)); } - else if (*(str + 1) == '<') + if (lexer->str[lexer->pos] == '<') { + token_free(token, 0); + (*alst)->content = token_init(); token->type = TK_DLESS; - token_append(token, str[1], 0); - return (ft_tokenize(&(*alst)->next, str + 2, DEFAULT)); + lexer->pos++; + push(&lexer->stack, DLESS); + lexer->state = DEFAULT; + ft_lsteadd(&lexer->heredoc_stack, ft_lstnew(alst, sizeof(alst))); + return (lexer_lex(&(*alst)->next, lexer)); } else { token->type = TK_LESS; - return (ft_tokenize(&(*alst)->next, str + 1, DEFAULT)); + lexer->state = DEFAULT; + return (lexer_lex(&(*alst)->next, lexer)); } } diff --git a/42sh/src/lexer/lexer_lessand.c b/42sh/src/lexer/lexer_lessand.c index fc6eef56..f411b225 100644 --- a/42sh/src/lexer/lexer_lessand.c +++ b/42sh/src/lexer/lexer_lessand.c @@ -6,27 +6,31 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/12/03 11:58:51 by jhalford #+# #+# */ -/* Updated: 2017/01/27 15:55:27 by wescande ### ########.fr */ +/* Updated: 2017/02/09 19:56:29 by jhalford ### ########.fr */ /* */ /* ************************************************************************** */ #include "lexer.h" -int lexer_lessand(t_list **alst, char *str) +int lexer_lessand(t_list **alst, t_lexer *lexer) { t_token *token; token = (*alst)->content; token->type = TK_LESSAND; - if (ft_isdigit(*str)) + if (ft_isdigit(lexer->str[lexer->pos])) { - token_append(token, *str, 0); - return (lexer_lessand(alst, str + 1)); + token_append(token, lexer, 0, 0); + lexer->pos++; + return (lexer_lessand(alst, lexer)); } - else if (*str == '-') + else if (lexer->str[lexer->pos] == '-') { - token_append(token, *str, 0); - return (ft_tokenize(&(*alst)->next, str + 1, DEFAULT)); + token_append(token, lexer, 0, 0); + lexer->pos++; + lexer->state = DEFAULT; + return (lexer_lex(&(*alst)->next, lexer)); } - return (ft_tokenize(alst, str, DEFAULT)); + lexer->state = DEFAULT; + return (lexer_lex(alst, lexer)); } diff --git a/42sh/src/lexer/ft_tokenize.c b/42sh/src/lexer/lexer_lex.c similarity index 65% rename from 42sh/src/lexer/ft_tokenize.c rename to 42sh/src/lexer/lexer_lex.c index 54b6a9cc..9e888bcf 100644 --- a/42sh/src/lexer/ft_tokenize.c +++ b/42sh/src/lexer/lexer_lex.c @@ -1,18 +1,23 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* ft_tokenize.c :+: :+: :+: */ +/* lexer_lex.c :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: jhalford +#+ +:+ +#+ */ +/* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ +<<<<<<< HEAD:src/lexer/ft_tokenize.c /* Created: 2016/11/10 13:37:11 by jhalford #+# #+# */ /* Updated: 2017/02/17 17:28:23 by ariard ### ########.fr */ +======= +/* Created: 2017/02/09 17:08:51 by jhalford #+# #+# */ +/* Updated: 2017/02/09 22:58:48 by jhalford ### ########.fr */ +>>>>>>> master:src/lexer/lexer_lex.c /* */ /* ************************************************************************** */ #include "lexer.h" -int (*g_lexer[])(t_list **alst, char *str) = +int (*g_lexer[])(t_list **alst, t_lexer *lexer) = { &lexer_default, &lexer_newline, @@ -20,16 +25,19 @@ int (*g_lexer[])(t_list **alst, char *str) = &lexer_sep, &lexer_word, &lexer_number, - &lexer_great, &lexer_less, - &lexer_greatand, + &lexer_great, &lexer_lessand, + &lexer_greatand, + &lexer_dless, &lexer_quote, &lexer_dquote, + &lexer_bquote, + &lexer_bquote, &lexer_backslash, - &lexer_var, - &lexer_special, + &lexer_paren, &lexer_comment, + &lexer_end, }; int ft_is_delim(char c) @@ -42,16 +50,16 @@ int ft_is_delim_list(char c) return (c == ';' || c == '\n' || c == '&'); } -int ft_tokenize(t_list **alst, char *str, t_lexstate state) +int lexer_lex(t_list **alst, t_lexer *lexer) { t_token *token; - if (!*str) - return (0); + if (lexer->str[lexer->pos] == 0) + return (lexer_end(alst, lexer)); if (!*alst) { token = token_init(); *alst = ft_lstnew(token, sizeof(*token)); } - return ((*g_lexer[state])(alst, str)); + return ((*g_lexer[lexer->state])(alst, lexer)); } diff --git a/42sh/src/lexer/lexer_newline.c b/42sh/src/lexer/lexer_newline.c index c18ac827..396dc6d3 100644 --- a/42sh/src/lexer/lexer_newline.c +++ b/42sh/src/lexer/lexer_newline.c @@ -6,13 +6,13 @@ /* By: ariard +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2017/01/23 23:19:46 by ariard #+# #+# */ -/* Updated: 2017/02/03 19:53:03 by ariard ### ########.fr */ +/* Updated: 2017/02/09 19:55:04 by jhalford ### ########.fr */ /* */ /* ************************************************************************** */ #include "lexer.h" -int lexer_newline(t_list **alst, char *str) +int lexer_newline(t_list **alst, t_lexer *lexer) { t_token *token; @@ -20,7 +20,7 @@ int lexer_newline(t_list **alst, char *str) { token = (*alst)->content; if (*token->data) - return (lexer_newline(&(*alst)->next, str)); + return (lexer_newline(&(*alst)->next, lexer)); } else { @@ -29,5 +29,5 @@ int lexer_newline(t_list **alst, char *str) } token = (*alst)->content; token->type = TK_NEWLINE; - return (ft_tokenize(&(*alst)->next, str + 1, DEFAULT)); + return (lexer_lex(&(*alst)->next, lexer)); } diff --git a/42sh/src/lexer/lexer_var.c b/42sh/src/lexer/lexer_newline.c~HEAD similarity index 52% rename from 42sh/src/lexer/lexer_var.c rename to 42sh/src/lexer/lexer_newline.c~HEAD index ab6e0b79..c18ac827 100644 --- a/42sh/src/lexer/lexer_var.c +++ b/42sh/src/lexer/lexer_newline.c~HEAD @@ -1,37 +1,33 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* lexer_var.c :+: :+: :+: */ +/* lexer_newline.c :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: jhalford +#+ +:+ +#+ */ +/* By: ariard +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ -/* Created: 2017/01/10 14:54:57 by jhalford #+# #+# */ -/* Updated: 2017/01/27 15:55:54 by wescande ### ########.fr */ +/* Created: 2017/01/23 23:19:46 by ariard #+# #+# */ +/* Updated: 2017/02/03 19:53:03 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ #include "lexer.h" -int lexer_var(t_list **alst, char *str) +int lexer_newline(t_list **alst, char *str) { t_token *token; - t_lexstate state; + if (*alst) + { + token = (*alst)->content; + if (*token->data) + return (lexer_newline(&(*alst)->next, str)); + } + else + { + token = token_init(); + *alst = ft_lstnew(token, sizeof(*token)); + } token = (*alst)->content; - token->type = TK_N_WORD; - str++; - if (!ft_strchr(token->data, '$')) - token_append(token, '$', 0); - if (!*str) - { - token_expand_var(token); - return (0); - } - if ((state = get_lexer_state(str))) - { - token_expand_var(token); - return (ft_tokenize(alst, str, state)); - } - token_append(token, *str, 0); - return (lexer_var(alst, str)); + token->type = TK_NEWLINE; + return (ft_tokenize(&(*alst)->next, str + 1, DEFAULT)); } diff --git a/42sh/src/lexer/lexer_number.c b/42sh/src/lexer/lexer_number.c index 5406bead..0508f70f 100644 --- a/42sh/src/lexer/lexer_number.c +++ b/42sh/src/lexer/lexer_number.c @@ -6,28 +6,34 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/12/03 12:06:45 by jhalford #+# #+# */ -/* Updated: 2017/02/03 14:50:09 by ariard ### ########.fr */ +/* Updated: 2017/02/20 20:53:20 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ #include "lexer.h" -int lexer_number(t_list **alst, char *str) +int lexer_number(t_list **alst, t_lexer *lexer) { t_token *token; t_lexstate state; token = (*alst)->content; - if ((state = get_lexer_state(str))) - return (ft_tokenize(alst, str, state)); - if (*str == '>') - return (ft_tokenize(alst, str, GREAT)); - else if (*str == '<') - return (ft_tokenize(alst, str, LESS)); - else if (ft_isdigit(*str)) + if ((state = get_state_global(lexer))) { - token_append(token, *str, 0); - return (lexer_number(alst, str + 1)); + lexer->state = state; + return (lexer_lex(alst, lexer)); } - return (ft_tokenize(alst, str, DEFAULT)); + else if ((state = get_state_redir(lexer))) + { + lexer->state = state; + return (lexer_lex(alst, lexer)); + } + else if (ft_isdigit(lexer->str[lexer->pos])) + { + token_append(token, lexer, 0, 0); + lexer->pos++; + return (lexer_number(alst, lexer)); + } + lexer->state = DEFAULT; + return (lexer_lex(alst, lexer)); } diff --git a/42sh/src/lexer/lexer_paren.c b/42sh/src/lexer/lexer_paren.c new file mode 100644 index 00000000..dd795357 --- /dev/null +++ b/42sh/src/lexer/lexer_paren.c @@ -0,0 +1,31 @@ +#include "lexer.h" + +int lexer_paren(t_list **alst, t_lexer *lexer) +{ + t_token *token; + t_list **lst; + + lst = alst; + if (*alst) + { + token = (*alst)->content; + if (token->type) + lst = &(*alst)->next; + } + token = token_init(); + *lst = ft_lstnew(token, sizeof(*token)); + token = (*lst)->content; + if (lexer->str[lexer->pos] == '(') + { + token->type = TK_PAREN_OPEN; + push(&lexer->stack, PAREN); + } + else if (lexer->stack && *(int*)lexer->stack->content == PAREN) + { + token->type = TK_PAREN_CLOSE; + pop(&lexer->stack); + } + lexer->pos++; + lexer->state = DEFAULT; + return (lexer_lex(&(*lst)->next, lexer)); +} diff --git a/42sh/src/lexer/lexer_quote.c b/42sh/src/lexer/lexer_quote.c index 4b99e6fe..9b1afbd1 100644 --- a/42sh/src/lexer/lexer_quote.c +++ b/42sh/src/lexer/lexer_quote.c @@ -6,21 +6,31 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/12/03 12:07:08 by jhalford #+# #+# */ -/* Updated: 2017/01/27 15:52:21 by wescande ### ########.fr */ +/* Updated: 2017/02/17 15:28:13 by jhalford ### ########.fr */ /* */ /* ************************************************************************** */ #include "lexer.h" -int lexer_quote(t_list **alst, char *str) +int lexer_quote(t_list **alst, t_lexer *lexer) { t_token *token; token = (*alst)->content; - token->type = TK_Q_WORD; - str++; - if (*str == '\'') - return (ft_tokenize(alst, str + 1, WORD)); - token_append(token, *str, 1); - return (lexer_quote(alst, str)); + token->type = TK_WORD; + if (lexer->str[lexer->pos] == '\'') + { + lexer->pos++; + if (!(lexer->stack && *(int*)lexer->stack->content == QUOTE)) + { + push(&lexer->stack, QUOTE); + return (lexer_lex(alst, lexer)); + } + lexer->state = WORD; + pop(&lexer->stack); + return (lexer_lex(alst, lexer)); + } + token_append(token, lexer, 1, 1); + lexer->pos++; + return (lexer_lex(alst, lexer)); } diff --git a/42sh/src/lexer/lexer_sep.c b/42sh/src/lexer/lexer_sep.c index fd1e1341..eb4420a6 100644 --- a/42sh/src/lexer/lexer_sep.c +++ b/42sh/src/lexer/lexer_sep.c @@ -6,21 +6,24 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/11/30 16:29:57 by jhalford #+# #+# */ -/* Updated: 2017/02/03 19:53:31 by ariard ### ########.fr */ +/* Updated: 2017/02/20 20:54:07 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ #include "lexer.h" -int lexer_sep(t_list **alst, char *str) +int lexer_sep(t_list **alst, t_lexer *lexer) { - t_token *token; + t_token *token; + char c; + char cn; + lexer->state = DEFAULT; if (*alst) { token = (*alst)->content; if (*token->data) - return (lexer_sep(&(*alst)->next, str)); + return (lexer_sep(&(*alst)->next, lexer)); } else { @@ -28,13 +31,13 @@ int lexer_sep(t_list **alst, char *str) *alst = ft_lstnew(token, sizeof(*token)); } token = (*alst)->content; - if (str[0] == '&') - token->type = str[1] == '&' ? TK_AND_IF : TK_AMP; - if (str[0] == '|') - token->type = str[1] == '|' ? TK_OR_IF : TK_PIPE; - token->type = (*str == ';') ? TK_SEMI : token->type; - return (ft_tokenize(&(*alst)->next, - str + 1 + - (token->type & (TK_AND_IF | TK_OR_IF) ? 1 : 0), - DEFAULT)); + c = lexer->str[lexer->pos]; + cn = lexer->str[lexer->pos + 1]; + if (c == '&') + token->type = cn == '&' ? TK_AND_IF : TK_AMP; + else if (c == '|') + token->type = cn == '|' ? TK_OR_IF : TK_PIPE; + token->type = (c == ';') ? TK_SEMI : token->type; + lexer->pos += 1 + (token->type & (TK_AND_IF | TK_OR_IF) ? 1 : 0); + return (lexer_lex(&(*alst)->next, lexer)); } diff --git a/42sh/src/lexer/lexer_word.c b/42sh/src/lexer/lexer_word.c index ef8b06e9..f8c7ea6b 100644 --- a/42sh/src/lexer/lexer_word.c +++ b/42sh/src/lexer/lexer_word.c @@ -6,25 +6,30 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/12/03 12:07:11 by jhalford #+# #+# */ -/* Updated: 2017/02/09 15:37:21 by ariard ### ########.fr */ +/* Updated: 2017/02/20 20:54:32 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ #include "lexer.h" -int lexer_word(t_list **alst, char *str) +int lexer_word(t_list **alst, t_lexer *lexer) { t_token *token; t_lexstate state; token = (*alst)->content; - token->type = TK_N_WORD; - if ((state = get_lexer_state(str))) - return (ft_tokenize(alst, str, state)); - if (*str == '>') - return (ft_tokenize(&(*alst)->next, str, GREAT)); - else if (*str == '<') - return (ft_tokenize(&(*alst)->next, str, LESS)); - token_append(token, *str, 0); - return (ft_tokenize(alst, str + 1, WORD)); + token->type = TK_WORD; + if ((state = get_state_global(lexer))) + { + lexer->state = state; + return (lexer_lex(alst, lexer)); + } + if ((state = get_state_redir(lexer))) + { + lexer->state = state; + return (lexer_lex(alst, lexer)); + } + token_append(token, lexer, 0, 0); + lexer->pos++; + return (lexer_lex(alst, lexer)); } diff --git a/42sh/src/lexer/reduce_parens.c b/42sh/src/lexer/reduce_parens.c index f3fcf66b..9df6e40d 100644 --- a/42sh/src/lexer/reduce_parens.c +++ b/42sh/src/lexer/reduce_parens.c @@ -6,7 +6,7 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2017/01/11 16:13:31 by jhalford #+# #+# */ -/* Updated: 2017/02/03 14:36:50 by ariard ### ########.fr */ +/* Updated: 2017/02/20 20:55:06 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ diff --git a/42sh/src/lexer/stack_to_prompt.c b/42sh/src/lexer/stack_to_prompt.c new file mode 100644 index 00000000..3a5cc8ff --- /dev/null +++ b/42sh/src/lexer/stack_to_prompt.c @@ -0,0 +1,38 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* stack_to_prompt.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/09 21:25:26 by jhalford #+# #+# */ +/* Updated: 2017/02/17 14:41:08 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "lexer.h" + +char *stack_to_prompt(t_list *stack) +{ + t_flag top; + + if (!stack) + return (NULL); + top = *(int*)stack->content; + if (top == BACKSLASH) + return ("> "); + else if (top == QUOTE) + return ("quote> "); + else if (top == DQUOTE) + return ("dquote> "); + else if (top == BQUOTE) + return ("bquote> "); + else if (top == DQUOTE_BQUOTE) + return ("dquote bquote> "); + else if (top == PAREN) + return ("subsh> "); + else if (top == DLESS) + return ("heredoc> "); + else + return ("error> "); +} diff --git a/42sh/src/lexer/token_append.c b/42sh/src/lexer/token_append.c index e49e5b56..8a65c2b5 100644 --- a/42sh/src/lexer/token_append.c +++ b/42sh/src/lexer/token_append.c @@ -6,15 +6,15 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/11/11 17:18:42 by jhalford #+# #+# */ -/* Updated: 2017/02/03 15:12:17 by ariard ### ########.fr */ +/* Updated: 2017/02/20 21:03:57 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ #include "lexer.h" -#define TOKEN_INCR 10 -int token_append(t_token *token, char c, short int esc) +int token_append_char(t_token *token, char c, + short int esc, short int esc2) { int len; @@ -23,12 +23,32 @@ int token_append(t_token *token, char c, short int esc) { token->size += 8; token->data = (char *)ft_realloc(token->data, token->size + 1); - token->esc = (unsigned char *)ft_realloc((char *)token->esc, - token->size / 8 + 1); - token->esc[token->size / 8 - 1] = 0; + token->esc = (unsigned char *)ft_memrealloc(token->esc, + (token->size >> 3), + (token->size >> 3) + 1); + token->esc[token->size >> 3] = 0; + token->esc2 = (unsigned char *)ft_memrealloc(token->esc2, + (token->size >> 3), + (token->size >> 3) + 1); + token->esc2[token->size >> 3] = 0; } - ft_strcat(token->data, (char[2]){c, '\0'}); - if (esc) - token->esc[len / 8] |= 1 << (7 - len % 8); + ft_strcat(token->data, (char[]){c, 0}); + token->esc[len >> 3] |= esc << (7 - len % 8); + token->esc2[len >> 3] |= esc2 << (7 - len % 8); return (0); } + +int token_append_str(t_token *token, char *str, + short int esc, short int esc2) +{ + while (*str) + if (token_append_char(token, *str++, esc, esc2)) + return (1); + return (0); +} + +int token_append(t_token *token, t_lexer *lexer, + short int esc, short int esc2) +{ + return (token_append_char(token, lexer->str[lexer->pos], esc, esc2)); +} diff --git a/42sh/src/lexer/token_free.c b/42sh/src/lexer/token_free.c index 60fe819d..09fb728f 100644 --- a/42sh/src/lexer/token_free.c +++ b/42sh/src/lexer/token_free.c @@ -6,7 +6,7 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/12/03 12:07:30 by jhalford #+# #+# */ -/* Updated: 2017/02/03 14:35:52 by ariard ### ########.fr */ +/* Updated: 2017/02/20 20:55:25 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ @@ -18,10 +18,8 @@ void token_free(void *data, size_t size) (void)size; token = data; - if (!(token->type & TK_NON_FREEABLE)) - { - ft_strdel(&token->data); - ft_memdel((void **)&token->esc); - } + ft_strdel(&token->data); + ft_memdel((void **)&token->esc); + ft_memdel((void **)&token->esc2); free(token); } diff --git a/42sh/src/lexer/token_init.c b/42sh/src/lexer/token_init.c index b0340755..dcf4a219 100644 --- a/42sh/src/lexer/token_init.c +++ b/42sh/src/lexer/token_init.c @@ -6,7 +6,7 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/11/10 15:30:25 by jhalford #+# #+# */ -/* Updated: 2017/02/03 14:35:39 by ariard ### ########.fr */ +/* Updated: 2017/02/20 20:55:35 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ @@ -21,6 +21,7 @@ t_token *token_init(void) token->type = 0; token->size = 8; token->data = ft_strnew(token->size + 1); - token->esc = (unsigned char *)ft_strnew(token->size / 8 + 1); + token->esc = (unsigned char *)ft_strnew((token->size >> 3)); + token->esc2 = (unsigned char *)ft_strnew((token->size >> 3)); return (token); } diff --git a/42sh/src/lexer/token_print.c b/42sh/src/lexer/token_print.c index 148e33f9..18d9b38e 100644 --- a/42sh/src/lexer/token_print.c +++ b/42sh/src/lexer/token_print.c @@ -6,7 +6,7 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/11/28 14:39:01 by jhalford #+# #+# */ -/* Updated: 2017/02/03 14:35:21 by ariard ### ########.fr */ +/* Updated: 2017/02/20 20:55:43 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ @@ -26,7 +26,7 @@ void token_print(t_list *lst) type = token->type; while (type >> (i++ + 2)) ; - DG("%02i '%s'", i, token->data); + DG("%02i:[%s]", i, token->data); index = -1; lst = lst->next; } diff --git a/42sh/src/line-editing/completion.c b/42sh/src/line-editing/completion.c new file mode 100644 index 00000000..0e09cc3f --- /dev/null +++ b/42sh/src/line-editing/completion.c @@ -0,0 +1,41 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* completion.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/03 14:15:55 by gwojda #+# #+# */ +/* Updated: 2017/02/16 14:22:44 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int ft_completion(int ret) +{ + size_t tmp; + size_t pos_tmp; + int beg_len; + char boolean; + + boolean = 0; + beg_len = ft_strlen(data_singleton()->line.input); + if (((ret != TOUCHE_TAB && ret != 10) + || (ret == 10)) && !(data_singleton()->comp)) + return (0); + tmp = POS; + pos_tmp = POS; + if (data_singleton()->comp || ret == TOUCHE_TAB) + boolean = completion(ret); + if (boolean || ret == 10) + { + ft_puttermcaps("cd"); + ft_current_str(STR, tmp); + ft_get_next_str(STR, &tmp); + ft_putnc('\b', tmp - + (pos_tmp + ft_strlen(data_singleton()->line.input) - beg_len)); + POS = pos_tmp + ft_strlen(data_singleton()->line.input) - beg_len; + } + return (1); +} diff --git a/42sh/src/line-editing/control_c_and_d.c b/42sh/src/line-editing/control_c_and_d.c new file mode 100644 index 00000000..d484cbaa --- /dev/null +++ b/42sh/src/line-editing/control_c_and_d.c @@ -0,0 +1,43 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* control_c_and_d.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/02 15:17:28 by gwojda #+# #+# */ +/* Updated: 2017/02/14 14:08:21 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void ft_buff_f6(void) +{ + int ret; + + ret = 0; + read(0, &ret, sizeof(int)); +} + +void ft_control_d(void) +{ + if (!STR || STR[0] == '\0') + { + ft_putstr("exit\n"); + builtin_exit(NULL, (char*[]){"exit", NULL}, NULL); + } + else if (POS < ft_strlen(STR)) + ft_del(); + else + ft_puttermcaps("bl"); +} + +void ft_control_c(void) +{ + ft_putchar('\n'); + set_exitstatus(1, 1); + ft_prompt(); + ft_strdel(&STR); + POS = 0; +} diff --git a/42sh/src/line-editing/copy_cut_paste.c b/42sh/src/line-editing/copy_cut_paste.c new file mode 100644 index 00000000..5bb0374e --- /dev/null +++ b/42sh/src/line-editing/copy_cut_paste.c @@ -0,0 +1,91 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* copy_cut_paste.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/19 12:45:06 by gwojda #+# #+# */ +/* Updated: 2017/02/05 17:07:12 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static char *ft_strdupi_space(char const *s) +{ + int i; + char *str; + + i = 0; + while (s[i] && s[i] != '\n') + ++i; + if (s[i] == '\n') + ++i; + str = (char *)malloc(sizeof(char) * (i + 1)); + if (str) + { + str[i] = '\0'; + --i; + while (i >= 0) + { + str[i] = s[i]; + --i; + } + } + return (str); +} + +void ft_v(void) +{ + size_t tmp_pos; + int i; + char *tmp; + + tmp = data_singleton()->line.copy_tmp; + i = -1; + tmp_pos = POS; + if (!STR || !tmp) + return ; + while (tmp[++i]) + STR = ft_realloc_imput(STR, tmp[i], POS + i); + if (POS) + { + --POS; + ft_get_beggin_with_curs(STR, &POS); + } + ft_current_str(STR, POS); + ft_get_next_str(STR, &POS); + ft_putnc('\b', POS - tmp_pos); + POS = tmp_pos; +} + +void ft_x(void) +{ + int i; + char **tmp; + + tmp = &data_singleton()->line.copy_tmp; + if (!STR) + return ; + if (*tmp) + ft_strdel(tmp); + *tmp = ft_strdupi_space(&STR[POS]); + i = ft_strlen(*tmp); + while (i >= 0) + { + STR = ft_remove_imput(STR, POS + i); + --i; + } + ft_puttermcaps("cd"); +} + +void ft_c(void) +{ + char *tmp; + + tmp = data_singleton()->line.copy_tmp; + if (tmp) + ft_strdel(&tmp); + tmp = ft_strdupi_space(STR + POS); +} diff --git a/42sh/src/line-editing/ft_prompt.c b/42sh/src/line-editing/ft_prompt.c new file mode 100644 index 00000000..a9a87efa --- /dev/null +++ b/42sh/src/line-editing/ft_prompt.c @@ -0,0 +1,107 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_prompt.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/13 13:51:33 by gwojda #+# #+# */ +/* Updated: 2017/02/16 14:27:57 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static int ft_git_status(void) +{ + int pip[2]; + int len; + char *tmp; + char *line; + pid_t soon; + char *exec[] = {"git", "status", "--porcelain", "--branch", NULL}; + + pipe(pip); + if ((soon = fork())) + { + wait(&soon); + if (WEXITSTATUS(soon)) + return (-1); + close(pip[1]); + get_next_line(pip[0], &line); + tmp = line; + if (ft_strrchr(line, '/')) + { + line = ft_strdup(ft_strrchr(line, '/') + 1); + ft_printf("\x1b[38;5;47mgit:(\x1b[38;5;203m%s\x1b[38;5;47m)", line); + free(tmp); + } + else + { + line = ft_strdup(line + 3); + ft_printf("\x1b[38;5;47mgit:(\x1b[38;5;203m%s\x1b[38;5;47m)", line); + free(tmp); + } + if (!get_next_line(pip[0], &tmp)) + printf("\x1b[38;5;83m %C ", L'✓'); + else + { + printf("\x1b[38;5;1m %C ", L'✗'); + free(tmp); + } + fflush(NULL); + } + else + { + dup2(pip[1], 1); + dup2(pip[1], 2); + close(pip[0]); + execve("/usr/bin/git", exec, data_singleton()->env); + } + len = ft_strlen(line); + ft_strdel(&line); + return (len + 8); +} + +static int ft_currend_dir(void) +{ + char **env; + char *pwd; + char *currend_dir; + + env = data_singleton()->env; + if (!(pwd = ft_getenv(env, "PWD"))) + return (-1); + if (ft_getenv(env, "HOME") && !ft_strcmp(pwd, ft_getenv(env, "HOME"))) + { + ft_printf("%c ", '~'); + return (1); + } + if (!(currend_dir = ft_strrchr(pwd, '/'))) + return (0); + if (!*(currend_dir + 1)) + { + ft_printf("%c ", '/'); + return (1); + } + ft_printf("%s ", currend_dir + 1); + return (ft_strlen(currend_dir + 1)); +} + +void ft_prompt() +{ + int ret; + + ret = 0; + do_job_notification(); + if (ft_getenv(data_singleton()->env, "?") && ft_atoi(ft_getenv(data_singleton()->env, "?"))) + printf("\x1b[38;5;1m%C ", L'➜'); + else + printf("\x1b[38;5;10m%C ", L'➜'); + fflush(NULL); + ft_putstr("\x1b[38;5;361m"); + ret += ft_currend_dir(); + ret += ft_git_status(); + ft_putstr("\033[22;37m"); + data_singleton()->line.prompt_size = ret + 4; +} diff --git a/42sh/src/line-editing/get_key.c b/42sh/src/line-editing/get_key.c new file mode 100644 index 00000000..30444e59 --- /dev/null +++ b/42sh/src/line-editing/get_key.c @@ -0,0 +1,77 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* get_key.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/19 16:28:49 by gwojda #+# #+# */ +/* Updated: 2017/02/14 11:16:09 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +t_key g_key[] = +{ + {FLECHE_HAUT , &ft_history_up }, + {FLECHE_BAS , &ft_history_down }, + {FLECHE_GAUCHE , &ft_move_left }, + {FLECHE_DROITE , &ft_move_right }, + {TOUCHE_DELETE , &ft_del }, + {TOUCHE_CTRL_C , &ft_control_c }, + {TOUCHE_CTRL_D , &ft_control_d }, + {TOUCHE_CTRL_R , &ft_surch_in_history }, + {TOUCHE_SUPPR , &ft_suppr }, + {TOUCHE_HOME , &ft_home }, + {TOUCHE_END , &ft_end }, + {TOUCHE_OPT_UP , &ft_up }, + {TOUCHE_OPT_DOWN , &ft_down }, + {TOUCHE_OPT_LEFT , &ft_found_prev_word }, + {TOUCHE_OPT_RIGHT , &ft_found_next_word }, + {TOUCHE_OPT_C , &ft_c }, + {TOUCHE_OPT_V , &ft_v }, + {TOUCHE_OPT_X , &ft_x }, + {TOUCHE_F5 , &ft_printall }, + {TOUCHE_F6 , &ft_buff_f6 }, + {0 , 0 }, +}; + +static void ft_is_str(void) +{ + if (STR) + { + ft_current_str(STR, POS); + ft_get_next_str(STR, &POS); + if (STR[POS]) + ++(POS); + } +} + +char *ft_read_stdin(void) +{ + int ret; + int j; + + ft_is_str(); + if (data_singleton()->comp) + c_clear(data_singleton()); + while (42) + { + ret = 0; + j = 0; + read(0, &ret, sizeof(int)); + if (ft_completion(ret)) + continue ; + while (g_key[j].value && g_key[j].value != ret) + ++j; + if (g_key[j].value) + g_key[j].f(); + else if (ft_isprint(ret)) + ft_print(ret); + else if (ret == 10) + return (STR); + else if (ft_isascii(ret) == 0) + ft_read_it(ret, &POS, &STR); + } +} diff --git a/42sh/src/line-editing/home_end.c b/42sh/src/line-editing/home_end.c new file mode 100644 index 00000000..707e5001 --- /dev/null +++ b/42sh/src/line-editing/home_end.c @@ -0,0 +1,51 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* home_end.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/14 11:13:24 by gwojda #+# #+# */ +/* Updated: 2017/02/14 11:13:47 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void ft_end(void) +{ + if (!STR) + return ; + if (POS) + { + --POS; + ft_get_beggin_with_curs(STR, &POS); + } + ft_puttermcaps("cd"); + while (STR[POS]) + ++POS; + ft_get_beggin(STR, &POS); + ft_current_str(STR, POS); + ft_get_next_str(STR, &POS); +} + +void ft_home(void) +{ + if (!STR) + return ; + if (POS) + { + --POS; + ft_get_beggin_with_curs(STR, &POS); + if (STR[POS + 1] == '\n') + ft_puttermcaps("nd"); + } + ft_puttermcaps("cd"); + POS = 0; + ft_current_str(STR, POS); + ft_get_next_str(STR, &POS); + ft_check_end_of_line(STR, POS); + if (!STR[POS]) + --POS; + ft_get_beggin_with_curs(STR, &POS); +} diff --git a/42sh/src/line-editing/lib_line_editing/tool_line.c b/42sh/src/line-editing/lib_line_editing/tool_line.c new file mode 100644 index 00000000..4047df37 --- /dev/null +++ b/42sh/src/line-editing/lib_line_editing/tool_line.c @@ -0,0 +1,62 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* tool_line.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/20 18:20:23 by gwojda #+# #+# */ +/* Updated: 2017/02/03 17:50:48 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void ft_get_beggin(char *str, size_t *pos) +{ + while ((*pos) && str[(*pos)] != '\n') + --(*pos); + if (*pos && str[(*pos)] == '\n') + ++(*pos); +} + +void ft_get_next_str(char *str, size_t *pos) +{ + while (str[(*pos)] && str[(*pos)] != '\n') + ++(*pos); + if (*pos && str[(*pos)] == '\n') + --(*pos); +} + +void ft_putall_current_str(char *str, size_t *pos) +{ + int len; + + len = 0; + ft_get_beggin(str, pos); + while (str[(*pos) + len] && str[(*pos) + len] != '\n') + ++len; + write(1, str + *pos, len); + ft_check_end_of_line(str, *pos + len); +} + +void ft_current_str(char *str, size_t pos) +{ + int len; + + len = 0; + while (str[pos + len] && str[pos + len] != '\n') + ++len; + write(1, str + pos, len); + ft_check_end_of_line(str, pos + len); +} + +int ft_strlen_next(char *str, size_t pos) +{ + int len; + + len = 0; + while (str[pos + len] && str[pos + len] != '\n') + ++len; + return (len); +} diff --git a/42sh/src/line-editing/lib_line_editing/tool_line_2.c b/42sh/src/line-editing/lib_line_editing/tool_line_2.c new file mode 100644 index 00000000..6753278a --- /dev/null +++ b/42sh/src/line-editing/lib_line_editing/tool_line_2.c @@ -0,0 +1,93 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* tool_line_2.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/20 19:07:52 by gwojda #+# #+# */ +/* Updated: 2017/02/05 17:06:07 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static void ft_clear_window(void) +{ + pid_t soon_pid; + char *tab_str[2]; + + tab_str[0] = "/usr/bin/clear"; + tab_str[1] = NULL; + soon_pid = fork(); + if (soon_pid != 0) + wait(NULL); + else + execve("/usr/bin/clear", tab_str, data_singleton()->env); +} + +static void ft_read_tmp(void) +{ + int ret; + + while (42) + { + ret = 0; + read(0, &ret, sizeof(int)); + if (ret == TOUCHE_F6) + { + ret = 0; + if (read(0, &ret, sizeof(int)) && ret == 126) + break ; + } + } +} + +void ft_change_affichage(void) +{ + ft_putstr("\033[31m"); + ft_puttermcaps("cd"); + ft_puttermcaps("sc"); + ft_putstr(STR); + ft_read_tmp(); + ft_puttermcaps("rc"); + ft_puttermcaps("cd"); + ft_putstr("\033[37m"); +} + +void ft_printall(void) +{ + size_t pos_tmp; + int ret; + + ret = 0; + if (read(0, &ret, sizeof(int)) == -1 || ret != 126 || !STR) + return ; + ft_clear_window(); + ft_prompt(); + pos_tmp = POS; + ft_change_affichage(); + if (POS) + --POS; + ft_get_beggin(STR, &POS); + ft_current_str(STR, POS); + ft_get_next_str(STR, &POS); + if (POS && !STR[POS]) + --POS; + if (POS) + ft_putnc('\b', POS - pos_tmp + 1); + POS = pos_tmp; +} + +void ft_get_beggin_with_curs(char *str, size_t *pos) +{ + while ((*pos) && str[(*pos)] != '\n') + { + --(*pos); + ft_puttermcaps("le"); + } + if (!*pos && str[(*pos)] != '\n') + ft_puttermcaps("le"); + if (str[(*pos)] == '\n') + ++(*pos); +} diff --git a/42sh/src/line-editing/lib_line_editing/toolz.c b/42sh/src/line-editing/lib_line_editing/toolz.c new file mode 100644 index 00000000..8f872021 --- /dev/null +++ b/42sh/src/line-editing/lib_line_editing/toolz.c @@ -0,0 +1,78 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* toolz.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/16 17:06:30 by gwojda #+# #+# */ +/* Updated: 2017/02/04 18:16:34 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void ft_putnc(char c, int n) +{ + int i; + + i = 0; + while (i < n) + { + write(1, &c, 1); + ++i; + } +} + +char *ft_strndup(char const *s, int n) +{ + int i; + char *str; + + i = 0; + str = (char *)malloc(sizeof(char) * (n + 1)); + if (str) + { + while (i < n) + { + str[i] = s[i]; + i++; + } + str[i] = '\0'; + } + return (str); +} + +char *ft_strdupi(char const *s) +{ + int i; + char *str; + + i = 0; + while (s[i] && s[i] != ';' && s[i] != '>' && s[i] != '<' + && ft_strncmp(s + i, "||", 2)) + i++; + str = (char *)malloc(sizeof(char) * (i + 1)); + if (str) + { + str[i--] = '\0'; + while (i >= 0) + { + str[i] = s[i]; + i--; + } + } + return (str); +} + +void ft_reset_tab(char *tabl) +{ + int i; + + i = 0; + while (tabl[i]) + { + tabl[i] = '\0'; + ++i; + } +} diff --git a/42sh/src/line-editing/lib_line_editing/toolz2.c b/42sh/src/line-editing/lib_line_editing/toolz2.c new file mode 100644 index 00000000..ea8836fe --- /dev/null +++ b/42sh/src/line-editing/lib_line_editing/toolz2.c @@ -0,0 +1,76 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* toolz2.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/07 11:00:28 by gwojda #+# #+# */ +/* Updated: 2017/02/20 14:32:08 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int ft_nbr_len(int nbr) +{ + if (nbr % 10 != nbr) + return (ft_nbr_len(nbr / 10) + 1); + else + return (1); +} + +void ft_puttermcaps(char *str) +{ + char *res; + char *env; + + env = getenv("TERM"); + if ((res = tgetstr(str, &env)) == NULL) + return ; + tputs(res, 0, ft_put); +} + +int ft_size_term(void) +{ + struct winsize w; + + ioctl(0, TIOCGWINSZ, &w); + return (w.ws_col); +} + +long long ft_pow(int nbr, int power) +{ + int i; + long long ret; + + i = 0; + ret = 1; + while (i < power) + { + ret *= nbr; + i++; + } + return (ret); +} + +char *ft_strdupi_w(char const *s) +{ + int i; + char *str; + + i = 0; + while (s[i] && s[i] != ' ' && s[i] != '\t') + i++; + str = (char *)malloc(sizeof(char) * (i + 1)); + if (str) + { + str[i--] = '\0'; + while (i >= 0) + { + str[i] = s[i]; + i--; + } + } + return (str); +} diff --git a/42sh/src/line-editing/lib_line_editing/toolz_parseur.c b/42sh/src/line-editing/lib_line_editing/toolz_parseur.c new file mode 100644 index 00000000..a0781e12 --- /dev/null +++ b/42sh/src/line-editing/lib_line_editing/toolz_parseur.c @@ -0,0 +1,51 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* toolz_parseur.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/16 16:14:46 by gwojda #+# #+# */ +/* Updated: 2017/02/02 14:29:34 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +char *ft_realloc_imput(char *str, int a, size_t pos) +{ + int i; + char tmp[2]; + char *str_tmp; + char *new_str; + + i = 0; + tmp[0] = (char)a; + tmp[1] = '\0'; + if (!str) + { + new_str = ft_strdup(tmp); + return (new_str); + } + str_tmp = ft_strndup(str, pos); + new_str = ft_strjoin(str_tmp, tmp); + free(str_tmp); + str_tmp = ft_strjoin(new_str, str + pos); + free(new_str); + free(str); + return (str_tmp); +} + +char *ft_remove_imput(char *str, size_t pos) +{ + char *new_str; + char *new_str2; + + if (!str) + return (str); + new_str = ft_strndup(str, pos); + new_str2 = ft_strjoin(new_str, &str[pos + 1]); + free(str); + free(new_str); + return (new_str2); +} diff --git a/42sh/src/line-editing/lib_line_editing/toolz_termcaps.c b/42sh/src/line-editing/lib_line_editing/toolz_termcaps.c new file mode 100644 index 00000000..637b5aef --- /dev/null +++ b/42sh/src/line-editing/lib_line_editing/toolz_termcaps.c @@ -0,0 +1,62 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* toolz_termcaps.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/08 12:35:11 by gwojda #+# #+# */ +/* Updated: 2017/02/14 11:13:10 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int ft_put(int nb) +{ + write(1, &nb, 1); + return (1); +} + +int ft_get_ind_prev(char *str, size_t pos) +{ + while (pos && str[pos] != '\n') + --pos; + return (pos); +} + +int ft_get_size_prev(char *str, size_t pos) +{ + size_t len; + + len = 0; + while (pos && str[pos] != '\n') + { + --pos; + ++len; + } + return (len); +} + +int ft_nb_last_line(char *str, size_t pos) +{ + int len; + + len = 1; + if (pos && str[pos] == '\n') + --pos; + len += data_singleton()->line.prompt_size; + len += ft_get_size_prev(str, pos); + return ((len) ? len % ft_size_term() : -1); +} + +void ft_check_end_of_line(char *str, size_t pos) +{ + if (!str) + return ; + if (ft_nb_last_line(str, pos) == 0) + { + ft_putchar(' '); + ft_puttermcaps("le"); + } +} diff --git a/42sh/src/line-editing/move_left_and_right.c b/42sh/src/line-editing/move_left_and_right.c new file mode 100644 index 00000000..b58bc789 --- /dev/null +++ b/42sh/src/line-editing/move_left_and_right.c @@ -0,0 +1,68 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* move_left_and_right.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/19 16:43:58 by gwojda #+# #+# */ +/* Updated: 2017/02/14 11:15:38 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void ft_move_right(void) +{ + size_t tmp; + + if (ft_strlen(STR) <= POS) + return ; + if (STR[POS] == '\n') + { + if (POS) + { + tmp = POS - 1; + ft_get_beggin_with_curs(STR, &tmp); + } + ft_puttermcaps("cd"); + ++POS; + ft_current_str(STR, POS); + ft_get_next_str(STR, &POS); + POS = (!STR[POS]) ? POS - 1 : POS; + ft_get_beggin_with_curs(STR, &POS); + } + else + { + ft_putchar(STR[POS]); + ++POS; + } +} + +void ft_move_left(void) +{ + if (!POS) + return ; + if (STR[POS - 1] == '\n') + { + if (POS - 1 == 0) + { + ft_puttermcaps("cd"); + --POS; + return ; + } + ft_puttermcaps("cd"); + POS -= 2; + ft_get_beggin(STR, &POS); + if (!POS && STR[POS] == '\n') + ++POS; + ft_current_str(STR, POS); + ft_get_next_str(STR, &POS); + ++POS; + } + else + { + ft_puttermcaps("le"); + --POS; + } +} diff --git a/42sh/src/line-editing/move_to_word.c b/42sh/src/line-editing/move_to_word.c new file mode 100644 index 00000000..703cc03d --- /dev/null +++ b/42sh/src/line-editing/move_to_word.c @@ -0,0 +1,127 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* move_to_word.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/14 11:12:09 by gwojda #+# #+# */ +/* Updated: 2017/02/14 11:12:19 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static void ft_init_prev_word(size_t *pos, char *str) +{ + int i; + + i = 0; + if (str[*pos - 1] != '\n' && !(str[*pos] == '\n' || str[*pos] == ' ')) + { + ft_puttermcaps("le"); + --(*pos); + } + while ((int)*pos - i - 1 > 0 && str[*pos - i - 1] == ' ') + { + ft_puttermcaps("le"); + ++i; + } + (*pos) = (i && str[*pos - i] == '\n') ? *pos - i + 1 : *pos - i; +} + +static void ft_found_prev_word_2(int i, char *str, size_t *pos) +{ + if (*pos && !(str[*pos] == '\n' || str[*pos] == ' ')) + { + ft_puttermcaps("le"); + --(*pos); + } + while (*pos - i && (str[*pos - i] == '\n' || str[*pos - i] == ' ')) + { + ft_puttermcaps("le"); + ++i; + } + while (*pos - i && str[*pos - i] != '\n' && str[*pos - i] != ' ') + { + ft_puttermcaps("le"); + ++i; + } + if (str[*pos - i] == '\n' || str[*pos - i] == ' ') + { + ft_puttermcaps("nd"); + ++(*pos); + } + (*pos) -= i; +} + +void ft_found_prev_word(void) +{ + int i; + + i = 0; + if (!POS || !STR) + return ; + ft_init_prev_word(&POS, STR); + if (POS >= 1 && STR[POS - 1] == '\n') + { + if (POS - 1 == 0) + { + ft_puttermcaps("cd"); + --POS; + return ; + } + ft_puttermcaps("cd"); + POS -= 2; + ft_get_beggin(STR, &POS); + if (!POS && STR[POS] == '\n') + ++POS; + ft_current_str(STR, POS); + ft_get_next_str(STR, &POS); + ++POS; + } + else + ft_found_prev_word_2(i, STR, &POS); +} + +static void ft_found_next_word_2(void) +{ + if (POS) + { + --POS; + ft_get_beggin_with_curs(STR, &POS); + } + ft_puttermcaps("cd"); + ft_get_next_str(STR, &POS); + POS += (POS || STR[0] != '\n') ? 2 : 1; + ft_current_str(STR, POS); + ft_get_next_str(STR, &POS); + if (!STR[POS]) + --POS; + ft_get_beggin_with_curs(STR, &POS); +} + +void ft_found_next_word(void) +{ + int i; + + i = 0; + if (!STR) + return ; + while (STR[i + POS] && STR[i + POS] == ' ') + { + ft_putchar(STR[i + POS]); + ++i; + } + if (STR[POS] == '\n') + ft_found_next_word_2(); + else + { + while (STR[i + POS] && STR[i + POS] != '\n' && STR[i + POS] != ' ') + { + ft_putchar(STR[i + POS]); + ++i; + } + POS += i; + } +} diff --git a/42sh/src/line-editing/move_up_and_down.c b/42sh/src/line-editing/move_up_and_down.c new file mode 100644 index 00000000..26eaa8d8 --- /dev/null +++ b/42sh/src/line-editing/move_up_and_down.c @@ -0,0 +1,99 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* move_up_and_down.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/09 13:21:40 by gwojda #+# #+# */ +/* Updated: 2017/02/14 11:18:54 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static void ft_up_2(size_t *pos, char *str) +{ + int len; + int i; + + i = 0; + len = ft_size_term(); + if (str[*pos - i] == '\n') + { + --len; + ft_puttermcaps("le"); + ++i; + } + while (*pos - i && str[*pos - i] != '\n' && --len + 1) + { + ft_puttermcaps("le"); + ++i; + } + if (str[*pos - i] == '\n') + { + ft_puttermcaps("nd"); + ++(*pos); + } + (*pos) -= i; +} + +void ft_up(void) +{ + int i; + + i = 0; + if (!STR || !POS) + return ; + if (STR[POS - 1] == '\n') + { + ft_puttermcaps("cd"); + if (POS >= 2) + POS -= 2; + ft_get_beggin(STR, &POS); + ft_current_str(STR, POS); + ft_get_next_str(STR, &POS); + ++POS; + } + else + ft_up_2(&POS, STR); +} + +static void ft_down_2(size_t *pos, char *str) +{ + if (*pos) + { + --(*pos); + ft_get_beggin_with_curs(str, pos); + } + ft_puttermcaps("cd"); + ft_get_next_str(str, pos); + (*pos) += 2; + ft_current_str(str, *pos); + ft_get_next_str(str, pos); + if (!(str[*pos])) + --(*pos); + ft_get_beggin_with_curs(str, pos); +} + +void ft_down(void) +{ + int i; + int len; + + i = 0; + if (!STR) + return ; + if (STR[POS] == '\n') + ft_down_2(&POS, STR); + else + { + len = ft_size_term(); + while (STR[i + POS] && STR[i + POS] != '\n' && --len + 1) + { + ft_putchar(STR[i + POS]); + ++i; + } + POS += i; + } +} diff --git a/42sh/src/line-editing/print_and_del.c b/42sh/src/line-editing/print_and_del.c new file mode 100644 index 00000000..8a83d184 --- /dev/null +++ b/42sh/src/line-editing/print_and_del.c @@ -0,0 +1,100 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* print_and_del.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/05 16:02:43 by gwojda #+# #+# */ +/* Updated: 2017/02/07 15:27:48 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int ft_found_next_char(char *str, size_t i) +{ + while (str[i]) + { + if (str[i] == '\n') + return (1); + ++i; + } + return (0); +} + +void ft_print(int ret) +{ + int j; + + j = 0; + STR = ft_realloc_imput(STR, ret, POS); + while (*(STR + POS + j) && *(STR + POS + j) != '\n') + { + ft_putchar(*(STR + POS + j)); + ++j; + } + ft_check_end_of_line(STR, POS + j); + ft_putnc('\b', j - 1); + ++POS; +} + +void ft_suppr_2(char **str, size_t *i, size_t tmp) +{ + ft_puttermcaps("cd"); + ft_current_str(*str, *i); + ft_get_next_str(*str, i); + if (*i && (*str)[*i] && ft_found_next_char(*str, *i)) + ++(*i); + ft_putnc('\b', *i - tmp); + (*i) = tmp; + if (ft_strlen(*str) == 0) + ft_strdel(str); +} + +void ft_suppr(void) +{ + size_t tmp; + char boolean; + + boolean = 0; + if (POS <= 0) + return ; + if (STR[POS - 1] != '\n') + boolean = 1; + --POS; + tmp = POS; + if (boolean) + { + ft_get_beggin_with_curs(STR, &POS); + STR = ft_remove_imput(STR, tmp); + } + else + { + STR = ft_remove_imput(STR, tmp); + ft_get_beggin(STR, &POS); + } + ft_suppr_2(&STR, &POS, tmp); +} + +void ft_del(void) +{ + size_t tmp; + + tmp = POS; + STR = ft_remove_imput(STR, tmp); + if (!(STR && POS < ft_strlen(STR) + 1)) + return ; + if (POS) + { + --POS; + ft_get_beggin_with_curs(STR, &POS); + } + ft_puttermcaps("cd"); + ft_current_str(STR, POS); + ft_get_next_str(STR, &POS); + if (STR[POS] && STR[POS] != '\n') + ++POS; + ft_putnc('\b', POS - tmp); + POS = tmp; +} diff --git a/42sh/src/line-editing/queue.c b/42sh/src/line-editing/queue.c new file mode 100644 index 00000000..c97e74fb --- /dev/null +++ b/42sh/src/line-editing/queue.c @@ -0,0 +1,73 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* queue.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/19 16:52:57 by gwojda #+# #+# */ +/* Updated: 2017/02/18 13:58:29 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static void ft_read_it_3(char **str, char t[5], size_t *pos, int *j) +{ + int i; + + i = 0; + while (i < 4 && t[i] == '\0') + ++i; + while (i < 4) + { + if (t[i] && ft_isprint(t[i])) + { + *str = ft_realloc_imput(*str, t[i], *pos); + ++(*pos); + ++(*j); + } + ++i; + } +} + +static void ft_read_it_2(int input, char t[5]) +{ + t[3] = (input / ft_pow(256, 3)) ? (input / ft_pow(256, 3)) : '\0'; + if (t[3]) + input = input % ft_pow(256, 3); + t[2] = (input / ft_pow(256, 2)) ? (input / ft_pow(256, 2)) : '\0'; + if (t[2]) + input = input % ft_pow(256, 2); + t[1] = (input / ft_pow(256, 1)) ? (input / ft_pow(256, 1)) : '\0'; + if (t[1]) + input = input % ft_pow(256, 1); + t[0] = (input / ft_pow(256, 0)) ? (input / ft_pow(256, 0)) : '\0'; + if (t[0]) + input = input % ft_pow(256, 0); + t[4] = '\0'; +} + +void ft_read_it(int input, size_t *pos, char **str) +{ + int j; + char t[5]; + size_t pos_tmp; + + j = 0; + pos_tmp = *pos; + if (input == TOUCHE_DELETE || input < 0 || input == 892427035 || + input == 126 || input == 993090331 || input == 925981467 || + input == 21298 || input == 892427035 || input == 8270395 || input == + 942758683 || input == 993090331 || input == 18489 || input == 17977) + return ; + ft_read_it_2(input, t); + ft_read_it_3(str, t, pos, &j); + if (!*str) + return ; + *pos = pos_tmp; + ft_current_str((*str), *pos); + ft_get_next_str((*str), pos); + ft_putnc('\b', *pos - (pos_tmp + j)); + *pos = (pos_tmp + j); +} diff --git a/42sh/src/line-editing/readline.c b/42sh/src/line-editing/readline.c new file mode 100644 index 00000000..5d9795ec --- /dev/null +++ b/42sh/src/line-editing/readline.c @@ -0,0 +1,110 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* readline.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/15 14:19:48 by gwojda #+# #+# */ +/* Updated: 2017/02/16 12:45:32 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void ft_init_line(void) +{ + data_singleton()->line.input = NULL; + data_singleton()->line.copy_tmp = NULL; + data_singleton()->line.pos = 0; + data_singleton()->line.prompt_size = 0; + data_singleton()->line.list_size = 0; + data_singleton()->line.list_end = NULL; + data_singleton()->line.list_beg = NULL; + data_singleton()->line.opt = 0; +} + +void ft_init_history(void) +{ + int fd; + char *str; + char *home; + char *path; + + if (!(home = ft_getenv(data_singleton()->env, "HOME"))) + return ; + path = ft_str3join(home, "/", ".42sh_history"); + fd = open(path, O_RDONLY); + if (fd == -1) + return ; + while (get_next_line(fd, &str) > 0) + { + ft_push_back_history(&data_singleton()->line.list_beg, + ft_create_history_list(str)); + free(str); + } + free(path); + free(str); + close(fd); +} + +struct termios *ft_save_termios(int save) +{ + static struct termios *term_save = NULL; + + if (save < 0) + { + free(term_save); + return (NULL); + } + if (save > 0) + { + term_save = (struct termios *)malloc(sizeof(struct termios)); + tcgetattr(0, term_save); + } + return (term_save); +} + +void ft_init_termios(void) +{ + struct termios term; + + tcgetattr(0, &term); + term.c_lflag &= ~(ECHO | ICANON | ISIG); + term.c_cc[VMIN] = 1; + term.c_cc[VTIME] = 0; + tcsetattr(0, TCSANOW, &term); +} + +void readline_init(char *prompt) +{ + static int beg = 0; + + if (!beg) + { + ft_init_line(); + ft_init_history(); + ft_save_termios(1); + beg = 1; + } + ft_init_termios(); + if (STR) + ft_strdel(&STR); + data_singleton()->line.list_cur = data_singleton()->line.list_beg; + POS = 0; + prompt ? ft_putstr(prompt) : ft_prompt(); +} + +char *readline(char *prompt) +{ + char *input; + + readline_init(prompt); + input = ft_read_stdin(); + ft_putchar('\n'); + if (!prompt) + input = ft_history_parsing(); + if (tcsetattr(0, TCSANOW, ft_save_termios(0)) == -1) + return (NULL); + return (input); +} diff --git a/42sh/src/main/data_init.c b/42sh/src/main/data_init.c index bf178888..12c47e05 100644 --- a/42sh/src/main/data_init.c +++ b/42sh/src/main/data_init.c @@ -6,7 +6,7 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/11/28 19:26:32 by jhalford #+# #+# */ -/* Updated: 2017/02/17 17:09:18 by ariard ### ########.fr */ +/* Updated: 2017/02/20 20:57:14 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,19 +16,25 @@ extern char **environ; int data_init(void) { - char *term_name; t_data *data; + char *term_name; data = data_singleton(); data->env = ft_sstrdup(environ); - data->opts = SHELL_OPTS_JOBC; + data->comp = NULL; + data->opts = SH_OPTS_JOBC; data->exec.process.path = NULL; data->exec.process.av = NULL; + data->exec.process.toclose = STDIN; data->exec.process.fdin = STDIN; data->exec.process.fdout = STDOUT; data->exec.process.pid = 0; data->exec.process.attributes = PROCESS_PIPESTART | PROCESS_PIPEEND; + data->exec.process.redirs = NULL; + data->exec.fd0save = fcntl(0, F_DUPFD_CLOEXEC); + data->exec.fd1save = fcntl(1, F_DUPFD_CLOEXEC); + data->exec.fd2save = fcntl(2, F_DUPFD_CLOEXEC); data->exec.aol_status = NULL; data->exec.aol_search = 0; @@ -36,6 +42,7 @@ int data_init(void) data->exec.job.pgid = 0; data->exec.job.attributes = 0; data->exec.job.first_process = 0; + data->jobc.first_job = NULL; data->jobc.current_id = 1; if ((term_name = ft_getenv(data->env, "TERM")) == NULL) diff --git a/42sh/src/main/data_singleton.c b/42sh/src/main/data_singleton.c index c215e7f9..e86abb8d 100644 --- a/42sh/src/main/data_singleton.c +++ b/42sh/src/main/data_singleton.c @@ -3,10 +3,10 @@ /* ::: :::::::: */ /* data_singleton.c :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: jhalford +#+ +:+ +#+ */ +/* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2017/01/10 11:36:39 by jhalford #+# #+# */ -/* Updated: 2017/01/22 00:37:13 by ariard ### ########.fr */ +/* Updated: 2017/02/20 20:57:52 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ diff --git a/42sh/src/main/main.c b/42sh/src/main/main.c index c2f55c2e..2db727e0 100644 --- a/42sh/src/main/main.c +++ b/42sh/src/main/main.c @@ -6,51 +6,92 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/12/06 18:40:58 by jhalford #+# #+# */ -/* Updated: 2017/02/06 18:54:43 by ariard ### ########.fr */ +/* Updated: 2017/02/20 20:59:49 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" -int shell_single_command(char *command) +int non_interactive_shell(char *command) { t_list *token; + t_lexer lexer; t_btree *ast; + lexer_init(&lexer); + lexer.str = command; token = NULL; ast = NULL; + while (lexer.str[lexer.pos]) + { + if (lexer.stack && *(int*)lexer.stack->content == BACKSLASH) + pop(&lexer.stack); + do { + lexer_lex(&token, &lexer); + } while (lexer.str[lexer.pos] == '\n'); + if (!token) + return (0); +// if (bquotes_expand(&token)) +// return (1); + //token_print(token); + if (ft_parse(&ast, &token)) + return (1); + if (ft_exec(&ast)) + return (1); + } + return (0); +} - DG("{inv}{mag}got command '%s'", command); - if (ft_lexer(&token, &command) || !token) - return (1); - token_print(token); -// if (ft_parse(&ast, &token)) +int interactive_shell() +{ + t_list *token; + t_list *ltoken; + t_lexer lexer; + t_btree *ast; + + lexer_init(&lexer); + token = NULL; + ast = NULL; + do { + char *str = readline(stack_to_prompt(lexer.stack)); + ft_strappend(&lexer.str, str); + if (get_lexer_stack(lexer) == BACKSLASH) + pop(&lexer.stack); + else if (get_lexer_stack(lexer) == DLESS) + lexer.state = DLESS; + ltoken = ft_lstlast(token); + if (lexer_lex(token ? <oken : &token, &lexer)) + return (1); + //token_print(token); + } while (get_lexer_stack(lexer)); +// if (bquotes_expand(&token)) // return (1); + if (!token) + return (0); + ft_add_str_in_history(lexer.str); + if (ft_parse(&ast, &token)) + return (1); btree_print(STDBUG, ast, &ft_putast); if (ft_exec(&ast)) return (1); + ft_strdel(&lexer.str); return (0); } int main(int ac, char **av) { + t_data *data; + + data = data_singleton(); setlocale(LC_ALL, ""); - DG("{inv}{bol}{gre}start of shell{eoc} job_control is %s", data_singleton()->opts & SHELL_OPTS_JOBC ? "ON" : "OFF"); shell_init(ac, av); - if (data_singleton()->opts & SHELL_OPTS_LC) +// DG("{inv}{bol}{gre}start of shell{eoc} JOBC is %s", SH_HAS_JOBC(data->opts)?"ON":"OFF"); + if (SH_IS_INTERACTIVE(data->opts)) { - shell_single_command(ft_strdup(shell_get_avdata())); - return (0); - } - if (data_singleton()->opts & SHELL_MODE_SCRIPT) - { - shell_script(); - return (0); - } - while (1) - { - if (shell_single_command(ft_strdup(data_singleton()->line.input)) < 0) - return (1); + while (1) + interactive_shell(); } + else + non_interactive_shell(shell_get_avdata()); return (0); } diff --git a/42sh/src/main/remove_trailing_esc_nl.c b/42sh/src/main/remove_trailing_esc_nl.c new file mode 100644 index 00000000..9d6fb232 --- /dev/null +++ b/42sh/src/main/remove_trailing_esc_nl.c @@ -0,0 +1,26 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* remove_trailing_esc_nl.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/09 16:52:34 by jhalford #+# #+# */ +/* Updated: 2017/02/09 17:00:33 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int remove_trailing_esc_nl(char *str) +{ + char *last; + + last = str + ft_strlen(str) - 1; + if (*last == '\\') + { + *last = 0; + return (1); + } + return (0); +} diff --git a/42sh/src/main/shell_exit.c b/42sh/src/main/shell_exit.c index 83e4becc..e1f7e052 100644 --- a/42sh/src/main/shell_exit.c +++ b/42sh/src/main/shell_exit.c @@ -6,7 +6,7 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/12/12 17:37:04 by jhalford #+# #+# */ -/* Updated: 2017/01/19 21:50:05 by ariard ### ########.fr */ +/* Updated: 2017/02/20 21:04:01 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,8 +14,9 @@ void shell_exit(void) { - DG("shell_exit()"); +// DG("shell_exit()"); data_exit(); - job_kill_all(); + if (SH_HAS_JOBC(data_singleton()->opts)) + job_kill_all(); tcsetattr(STDIN, TCSANOW, &data_singleton()->jobc.shell_tmodes); } diff --git a/42sh/src/main/shell_get_opts.c b/42sh/src/main/shell_get_opts.c index cd56439a..c5a08dab 100644 --- a/42sh/src/main/shell_get_opts.c +++ b/42sh/src/main/shell_get_opts.c @@ -6,7 +6,7 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2017/01/11 14:04:48 by jhalford #+# #+# */ -/* Updated: 2017/01/30 20:29:48 by ariard ### ########.fr */ +/* Updated: 2017/02/20 21:00:13 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,7 +15,7 @@ static void shell_parse_long_opt(char *str) { if (ft_strcmp("no-jobcontrol", str) == 0) - data_singleton()->opts &= ~SHELL_OPTS_JOBC; + data_singleton()->opts &= ~SH_OPTS_JOBC; } static void shell_parse_short_opt(char *str) @@ -27,8 +27,9 @@ static void shell_parse_short_opt(char *str) { if (*str == 'c') { - data_singleton()->opts |= SHELL_OPTS_LC; - data_singleton()->opts &= ~SHELL_OPTS_JOBC; + data_singleton()->opts |= SH_OPTS_LC; + data_singleton()->opts &= ~SH_OPTS_JOBC; + data_singleton()->opts &= ~SH_INTERACTIVE; } i++; } @@ -39,6 +40,8 @@ void shell_get_opts(int ac, char **av) int i; i = 1; + if (isatty(STDIN)) + data_singleton()->opts |= SH_INTERACTIVE; while (i < ac && av[i][0] == '-') { if (ft_strcmp(av[i], "--") == 0) diff --git a/42sh/src/main/shell_init.c b/42sh/src/main/shell_init.c index 1fecc226..26c73eb6 100644 --- a/42sh/src/main/shell_init.c +++ b/42sh/src/main/shell_init.c @@ -6,7 +6,7 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/12/12 17:23:59 by jhalford #+# #+# */ -/* Updated: 2017/01/31 20:02:04 by ariard ### ########.fr */ +/* Updated: 2017/02/20 21:00:32 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,14 +15,18 @@ void shell_init(int ac, char **av) { int *shell_pgid; + t_data *data; data_init(); - data_singleton()->argc = ac; - data_singleton()->argv = ft_sstrdup(av); + data = data_singleton(); + data->argc = ac; + data->argv = ft_sstrdup(av); atexit(&shell_exit); - if (isatty(STDIN)) + shell_get_opts(ac, av); + if (SH_IS_INTERACTIVE(data->opts)) { - shell_pgid = &data_singleton()->jobc.shell_pgid; + DG("interactive shell settings"); + shell_pgid = &data->jobc.shell_pgid; while (tcgetpgrp(STDIN) != (*shell_pgid = getpgrp())) kill(-*shell_pgid, SIGTTIN); signal(SIGINT, sigint_handler); @@ -38,8 +42,6 @@ void shell_init(int ac, char **av) exit (1); } tcsetpgrp(STDIN, *shell_pgid); - tcgetattr(STDIN, &data_singleton()->jobc.shell_tmodes); + tcgetattr(STDIN, &data->jobc.shell_tmodes); } - read_script(av[1]); - shell_get_opts(ac, av); } diff --git a/42sh/src/parser/ft_parse.c b/42sh/src/parser/ft_parse.c index 60ed5f26..4d1a3c7d 100644 --- a/42sh/src/parser/ft_parse.c +++ b/42sh/src/parser/ft_parse.c @@ -5,8 +5,8 @@ /* +:+ +:+ +:+ */ /* By: ariard +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ -/* Created: 2017/02/09 14:30:22 by ariard #+# #+# */ -/* Updated: 2017/02/20 19:03:07 by ariard ### ########.fr */ +/* Created: 2016/11/30 17:14:58 by jhalford #+# #+# */ +/* Updated: 2017/02/20 21:01:51 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,7 +15,6 @@ static void insert_linebreak(t_list **lst) { t_token *token; - token = (*lst)->content; token->type = LINEBREAK; } @@ -67,6 +66,6 @@ int ft_parse2(t_btree **ast, t_list **token) { ft_putstr("syntax error: unexpected end of file\n"); return (0); - } + } return (0); } diff --git a/42sh/src/parser/parse_dgreat.c b/42sh/src/parser/parse_dgreat.c index 960be5ee..d1f19571 100644 --- a/42sh/src/parser/parse_dgreat.c +++ b/42sh/src/parser/parse_dgreat.c @@ -6,7 +6,7 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/11/14 12:49:45 by jhalford #+# #+# */ -/* Updated: 2017/02/09 21:22:16 by ariard ### ########.fr */ +/* Updated: 2017/02/20 21:02:01 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ diff --git a/42sh/src/parser/parse_dless.c b/42sh/src/parser/parse_dless.c index d9526c69..77c671e9 100644 --- a/42sh/src/parser/parse_dless.c +++ b/42sh/src/parser/parse_dless.c @@ -6,7 +6,7 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/12/03 13:31:40 by jhalford #+# #+# */ -/* Updated: 2017/02/03 16:43:10 by ariard ### ########.fr */ +/* Updated: 2017/02/20 21:02:10 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ @@ -26,7 +26,8 @@ int parse_dless(t_btree **ast, t_list **start, t_list **lst) next_tok = (*lst)->next->content; if (next_tok->type != TK_WORD) return (1); - node->data.redir.word.word = ft_strdup(next_tok->data); + node->data.redir.word.word = ft_strdup(tok->data); + node->data.redir.n = 0; ft_lst_delif(start, (*lst)->content, &ft_addrcmp, &token_free); ft_lst_delif(start, (*lst)->next->content, &ft_addrcmp, &token_free); ft_parse(&(*ast)->left, start); diff --git a/42sh/src/parser/parse_great.c b/42sh/src/parser/parse_great.c index 91420222..d4a77383 100644 --- a/42sh/src/parser/parse_great.c +++ b/42sh/src/parser/parse_great.c @@ -6,7 +6,7 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/11/14 12:49:45 by jhalford #+# #+# */ -/* Updated: 2017/02/15 19:30:06 by ariard ### ########.fr */ +/* Updated: 2017/02/20 21:02:17 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ @@ -26,7 +26,7 @@ int parse_great(t_btree **ast, t_list **start, t_list **lst) next_tok = (*lst)->next->content; if (!(next_tok->type & TK_WORD)) return (1); - node->data.redir.n = ft_atoi(tok->data); + node->data.redir.n = *tok->data == '>' ? 1 : ft_atoi(tok->data); node->data.redir.word.word = ft_strdup(next_tok->data); ft_lst_delif(start, (*lst)->content, &ft_addrcmp, &token_free); ft_lst_delif(start, (*lst)->next->content, &ft_addrcmp, &token_free); diff --git a/42sh/src/parser/parse_greatand.c b/42sh/src/parser/parse_greatand.c index 6dbbb7d8..eb93503d 100644 --- a/42sh/src/parser/parse_greatand.c +++ b/42sh/src/parser/parse_greatand.c @@ -6,7 +6,7 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/11/14 12:49:45 by jhalford #+# #+# */ -/* Updated: 2017/02/03 16:44:39 by ariard ### ########.fr */ +/* Updated: 2017/02/20 21:02:27 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ @@ -22,6 +22,7 @@ int parse_greatand(t_btree **ast, t_list **start, t_list **lst) node->type = TK_GREATAND; tok = (*lst)->content; and = ft_strchr(tok->data, '&'); + node->data.redir.n = *tok->data == '>' ? 1 : ft_atoi(tok->data); node->data.redir.word.fd = ft_atoi(and + 1); node->data.redir.close = tok->data[ft_strlen(tok->data) - 1] == '-' ? 1 : 0; diff --git a/42sh/src/parser/parse_less.c b/42sh/src/parser/parse_less.c index aaa9e994..ea34770c 100644 --- a/42sh/src/parser/parse_less.c +++ b/42sh/src/parser/parse_less.c @@ -6,7 +6,7 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/11/14 12:49:45 by jhalford #+# #+# */ -/* Updated: 2017/02/17 16:45:35 by ariard ### ########.fr */ +/* Updated: 2017/02/20 21:02:38 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ @@ -24,9 +24,9 @@ int parse_less(t_btree **ast, t_list **start, t_list **lst) return (1); tok = (*lst)->content; next_tok = (*lst)->next->content; - if (next_tok->type != TK_WORD) + if (!(next_tok->type & TK_WORD)) return (1); - node->data.redir.n = ft_atoi(tok->data); + node->data.redir.n = *tok->data == '>' ? 0 : ft_atoi(tok->data); node->data.redir.word.word = ft_strdup(next_tok->data); ft_lst_delif(start, (*lst)->content, &ft_addrcmp, &token_free); ft_lst_delif(start, (*lst)->next->content, &ft_addrcmp, &token_free); diff --git a/42sh/src/parser/parse_lessand.c b/42sh/src/parser/parse_lessand.c index e180d418..636421ba 100644 --- a/42sh/src/parser/parse_lessand.c +++ b/42sh/src/parser/parse_lessand.c @@ -6,7 +6,7 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/11/14 12:49:45 by jhalford #+# #+# */ -/* Updated: 2017/02/03 16:44:09 by ariard ### ########.fr */ +/* Updated: 2017/02/20 21:02:46 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ @@ -22,6 +22,7 @@ int parse_lessand(t_btree **ast, t_list **start, t_list **lst) node->type = TK_LESSAND; tok = (*lst)->content; and = ft_strchr(tok->data, '&'); + node->data.redir.n = *tok->data == '<' ? 0 : ft_atoi(tok->data); node->data.redir.word.fd = ft_atoi(and + 1); node->data.redir.close = tok->data[ft_strlen(tok->data) - 1] == '-' ? 1 : 0; diff --git a/42sh/src/parser/parse_redir.c b/42sh/src/parser/parse_redir.c new file mode 100644 index 00000000..4d209f62 --- /dev/null +++ b/42sh/src/parser/parse_redir.c @@ -0,0 +1,34 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* parse_redir.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/02 18:58:27 by jhalford #+# #+# */ +/* Updated: 2017/02/06 16:07:08 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "parser.h" + +int parse_redir(t_btree **ast, t_list **start, t_list **lst) +{ + t_token *tok; + + tok = (*lst)->content; + if (tok->type == TK_LESS) + return (parse_less(ast, start, lst)); + else if (tok->type == TK_GREAT) + return (parse_great(ast, start, lst)); + else if (tok->type == TK_DLESS) + return (parse_dless(ast, start, lst)); + else if (tok->type == TK_DGREAT) + return (parse_dgreat(ast, start, lst)); + else if (tok->type == TK_LESSAND) + return (parse_lessand(ast, start, lst)); + else if (tok->type == TK_GREATAND) + return (parse_greatand(ast, start, lst)); + else + return (-42); +} diff --git a/42sh/src/parser/parse_subshell.c b/42sh/src/parser/parse_subshell.c index a6255173..2177a919 100644 --- a/42sh/src/parser/parse_subshell.c +++ b/42sh/src/parser/parse_subshell.c @@ -6,7 +6,7 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2017/01/11 16:52:44 by jhalford #+# #+# */ -/* Updated: 2017/02/03 16:45:35 by ariard ### ########.fr */ +/* Updated: 2017/02/20 21:02:58 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ @@ -19,6 +19,11 @@ int parse_subshell(t_btree **ast, t_list **start, t_list **lst) (void)start; token = (*lst)->content; + if ((*lst)->next && ((t_token*)(*lst)->next->content)->type & TK_WORD) + { + ft_dprintf(2, "{red}%s: parse error near ')'{eoc}\n", SHELL_NAME); + return (-1); + } node = (*ast)->item; node->type = TK_SUBSHELL; node->data.sstr = malloc(4 * sizeof(char *)); diff --git a/42sh/src/parser/parse_word.c b/42sh/src/parser/parse_word.c index 8df72e27..95a79202 100644 --- a/42sh/src/parser/parse_word.c +++ b/42sh/src/parser/parse_word.c @@ -6,7 +6,7 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/11/14 12:49:45 by jhalford #+# #+# */ -/* Updated: 2017/02/15 19:54:27 by ariard ### ########.fr */ +/* Updated: 2017/02/20 21:03:20 by ariard ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,16 +16,19 @@ int parse_word(t_btree **ast, t_list **start, t_list **lst) { t_astnode *node; t_token *token; - char **my_tab; + char **the_tab; - DG("parse word begin"); - my_tab = NULL; token = (*lst)->content; node = (*ast)->item; node->type = TK_COMMAND; - my_tab = ft_sstradd(my_tab, token->data); - my_tab = ft_sstradd(my_tab, (char *)token->esc); - ft_ld_pushback(&node->data.token, my_tab); + if ((the_tab = (char **)malloc(sizeof(char *) * 4))) + { + the_tab[0] = ft_strdup(token->data); + the_tab[1] = (char *)dup_char_esc(token->esc, token->size >> 3); + the_tab[2] = (char *)dup_char_esc(token->esc2, token->size >> 3); + the_tab[3] = NULL; + } + ft_ld_pushback(&node->data.token, the_tab); ft_parse(ast, &(*lst)->next); ft_lst_delif(start, (*lst)->content, &ft_addrcmp, &token_free); DG("parse word end");