diff --git a/42sh/.gitignore b/42sh/.gitignore new file mode 100644 index 00000000..202ebc2f --- /dev/null +++ b/42sh/.gitignore @@ -0,0 +1,20 @@ +minishell +21sh +42sh +out +STDBUG +debug +.42sh_history +*.dSYM +.script.sh.swp +*.swp +*.swo +*.o +*.swn +STDBUG +STDEBUG +display_env +read_on_stdin +write_on_stderr +write_on_stdout +write_on_stdout_and_stderr diff --git a/42sh/.gitmodules b/42sh/.gitmodules new file mode 100644 index 00000000..17349de1 --- /dev/null +++ b/42sh/.gitmodules @@ -0,0 +1,3 @@ +[submodule "libft"] + path = libft + url = https://github.com/jzck/libft.git diff --git a/42sh/.tags b/42sh/.tags new file mode 100644 index 00000000..05a93ff6 --- /dev/null +++ b/42sh/.tags @@ -0,0 +1,48 @@ +HAS_CDOPT_L src/builtin/builtin_cd.c /^#define HAS_CDOPT_L(x) (x & CD_OPT_L)$/ +HAS_CDOPT_P src/builtin/builtin_cd.c /^#define HAS_CDOPT_P(x) (x & CD_OPT_P)$/ +Mmain src/main/main.c /^int main(void)$/ +builtin_cd src/builtin/builtin_cd.c /^int builtin_cd(char **av, char ***env_p)$/ +builtin_cd_opts src/builtin/builtin_cd.c /^int builtin_cd_opts(char **av, int *opts)$/ +builtin_cd_special src/builtin/builtin_cd.c /^char *builtin_cd_special(char **av, char **env)$/ +builtin_echo src/builtin/builtin_echo.c /^int builtin_echo(char **av, char ***env_p)$/ +builtin_env src/builtin/builtin_env.c /^int builtin_env(char **av, char ***env_p)$/ +builtin_exit src/builtin/builtin_exit.c /^int builtin_exit(char **av, char ***env_p)$/ +builtin_setenv src/builtin/builtin_setenv.c /^int builtin_setenv(char **av, char ***env_p)$/ +builtin_unsetenv src/builtin/builtin_unsetenv.c /^int builtin_unsetenv(char **av, char ***env_p)$/ +ft_builtin src/builtin/builtin.c /^int ft_builtin(char **av, char ***env_p)$/ +ft_clear_line src/line-editing/ft_clear_line.c /^int ft_clear_line(t_data *data, t_dlist **input_c/ +ft_cmd_exec src/minishell-exec/ft_cmd.c /^int ft_cmd_exec(char *execpath, char **argv, char/ +ft_cmd_getav src/minishell-exec/ft_cmd.c /^char **ft_cmd_getav(char *cmd)$/ +ft_cmd_process src/minishell-exec/ft_cmd.c /^int ft_cmd_process(char **argv, char ***env_p)$/ +ft_cursor_left src/line-editing/ft_cursor_left.c /^int ft_cursor_left(t_data *data, t_dlist **input_/ +ft_cursor_right src/line-editing/ft_cursor_right.c /^int ft_cursor_right(t_data *data, t_dlist **input/ +ft_env_getval src/main/lib_env.c /^char *ft_env_getval(char **env, char *key)$/ +ft_expand_dollar src/main/lib_expansion.c /^void ft_expand_dollar(char **av, char **env)$/ +ft_history_add src/line-editing/ft_history_add.c /^int ft_history_add(t_data *data, t_dlist *input_c/ +ft_history_down src/line-editing/ft_history_down.c /^int ft_history_down(t_data *data, t_dlist **input/ +ft_history_up src/line-editing/ft_history_up.c /^int ft_history_up(t_data *data, t_dlist **input_c/ +ft_input_is_escaped src/line-editing/ft_input_is_escaped.c /^int ft_input_is_escaped(t_dlist *input_chain)$/ +ft_interactive_sh src/line-editing/ft_interactive_sh.c /^int ft_interactive_sh(t_data *data)$/ +ft_key_basic src/line-editing/ft_key_basic.c /^int ft_key_basic(t_data *data, t_dlist **input_cha/ +ft_key_ctrl_d src/line-editing/ft_key_ctrl_d.c /^int ft_key_ctrl_d(t_data *data, t_dlist **input_c/ +ft_key_del src/line-editing/ft_key_del.c /^int ft_key_del(t_data *data, t_dlist **input_chai/ +ft_key_enter src/line-editing/ft_key_enter.c /^int ft_key_enter(t_data *data, t_dlist **input_ch/ +ft_line_end src/line-editing/ft_line_end.c /^int ft_line_end(t_data *data, t_dlist **input_cha/ +ft_line_go_down src/line-editing/ft_line_down.c /^int ft_line_go_down(t_dlist **input_chain)$/ +ft_line_go_up src/line-editing/ft_line_up.c /^int ft_line_go_up(t_dlist **input_chain)$/ +ft_line_start src/line-editing/ft_line_start.c /^int ft_line_start(t_data *data, t_dlist **input_c/ +ft_path_access src/main/lib_path.c /^int ft_path_access(char *execpath, char *execname/ +ft_path_findexec src/main/lib_path.c /^char *ft_path_findexec(char **path, char *execname/ +ft_prompt src/line-editing/ft_prompt.c /^int ft_prompt(void)$/ +ft_tc_init src/line-editing/ft_tc_init.c /^int ft_tc_init(t_data *data)$/ +ft_tokenize src/token/ft_tokenize.c /^int ft_tokenize(t_list **alst, char *str)$/ +ft_word_left src/line-editing/ft_word_left.c /^int ft_word_left(t_data *data, t_dlist **input_ch/ +ft_word_right src/line-editing/ft_word_right.c /^int ft_word_right(t_data *data, t_dlist **input_c/ +is_separator src/token/token_getnext.c /^static int is_separator(char c)$/ +is_stop_char src/token/token_getnext.c /^static int is_stop_char(char c)$/ +sig_handler src/main/sig_handler.c /^void sig_handler(int signo)$/ +token_append src/token/token_append.c /^int token_append(t_token *token, char c)$/ +token_free src/token/token_free.c /^void token_free(void *data, size_t size)$/ +token_getnext src/token/token_getnext.c /^t_token *token_getnext(int *pos, char *line)$/ +token_init src/token/token_init.c /^t_token *token_init()$/ +token_print src/token/token_print.c /^void token_print(t_list *lst)$/ diff --git a/42sh/Makefile b/42sh/Makefile new file mode 100644 index 00000000..421e55a7 --- /dev/null +++ b/42sh/Makefile @@ -0,0 +1,375 @@ +# **************************************************************************** # +# # +# ::: :::::::: # +# Makefile :+: :+: :+: # +# +:+ +:+ +:+ # +# By: wescande +#+ +:+ +#+ # +# +#+#+#+#+#+ +#+ # +# Created: 2016/08/29 21:32:58 by wescande #+# #+# # +# Updated: 2017/03/29 17:03:53 by ariard ### ########.fr # +# # +# **************************************************************************** # + +NAME = 42sh + +CC = gcc +FLAGS = -Wall -Wextra -Werror +D_FLAGS = -g + +DELTA = $$(echo "$$(tput cols)-47"|bc) + +LIBFT_DIR = libft/ +LIBFT_LIB = $(LIBFT_DIR)libft.a +LIBFT_INC = $(LIBFT_DIR)includes/ + +LIBS = -ltermcap + +SRC_DIR = src/ +INC_DIR = includes/ +OBJ_DIR = objs/ + +SRC_BASE = \ +builtin/bt_env_opt.c\ +builtin/bt_read_get.c\ +builtin/bt_read_term.c\ +builtin/builtin_cd.c\ +builtin/builtin_echo.c\ +builtin/builtin_env.c\ +builtin/builtin_exit.c\ +builtin/builtin_export.c\ +builtin/builtin_func.c\ +builtin/builtin_hash.c\ +builtin/builtin_history.c\ +builtin/builtin_math.c\ +builtin/builtin_read.c\ +builtin/builtin_setenv.c\ +builtin/builtin_unset.c\ +builtin/builtin_unsetenv.c\ +builtin/is_builtin.c\ +completion/c_arrow.c\ +completion/c_clear.c\ +completion/c_find_abspath.c\ +completion/c_find_binary.c\ +completion/c_find_env.c\ +completion/c_find_files.c\ +completion/c_init.c\ +completion/c_match.c\ +completion/c_match_glob.c\ +completion/c_match_update.c\ +completion/c_misc.c\ +completion/c_output.c\ +completion/c_parser.c\ +completion/c_pathsolver.c\ +completion/c_printer.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_bang.c\ +exec/exec_case_branch.c\ +exec/exec_destroy.c\ +exec/exec_elif.c\ +exec/exec_else.c\ +exec/exec_func.c\ +exec/exec_init.c\ +exec/exec_leaf.c\ +exec/exec_or_if.c\ +exec/exec_pipe.c\ +exec/exec_semi.c\ +exec/exec_var.c\ +exec/fd_is_valid.c\ +exec/ft_exec.c\ +exec/ft_findexec.c\ +exec/is_function.c\ +exec/mark_process_status.c\ +exec/node_copy.c\ +exec/pfree_cmd.c\ +exec/pfree_cond.c\ +exec/pfree_func.c\ +exec/pfree_list.c\ +exec/pfree_subshell.c\ +exec/plaunch_brace.c\ +exec/plaunch_builtin.c\ +exec/plaunch_case.c\ +exec/plaunch_empty.c\ +exec/plaunch_file.c\ +exec/plaunch_for.c\ +exec/plaunch_function.c\ +exec/plaunch_if.c\ +exec/plaunch_subshell.c\ +exec/plaunch_until.c\ +exec/plaunch_while.c\ +exec/process_launch.c\ +exec/process_redirect.c\ +exec/process_set.c\ +exec/process_setgroup.c\ +exec/process_setsig.c\ +exec/pset_brace.c\ +exec/pset_case.c\ +exec/pset_cmd.c\ +exec/pset_for.c\ +exec/pset_if.c\ +exec/pset_subshell.c\ +exec/pset_until.c\ +exec/pset_while.c\ +exec/redir_copy.c\ +exec/redir_free.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\ +exec/token_to_argv.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_home.c\ +glob/expand_var.c\ +glob/ft_strsplit_esc.c\ +glob/ft_strsplit_spe.c\ +glob/gen_tab_esc.c\ +glob/glob.c\ +glob/is_char_esc.c\ +glob/lib_perso/ft_ld_back.c\ +glob/lib_perso/ft_ld_clear.c\ +glob/lib_perso/ft_ld_copy.c\ +glob/lib_perso/ft_ld_del.c\ +glob/lib_perso/ft_ld_front.c\ +glob/lib_perso/ft_ld_new.c\ +glob/lib_perso/ft_ld_order.c\ +glob/lib_perso/ft_ld_pushback.c\ +glob/lib_perso/ft_ld_pushfront.c\ +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\ +glob/tab_esc_copy.c\ +glob/word_is_assignment.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\ +job_control/do_job_notification.c\ +job_control/has_running_job.c\ +job_control/has_stopped_job.c\ +job_control/job_addprocess.c\ +job_control/job_cmp_id.c\ +job_control/job_format.c\ +job_control/job_format_head.c\ +job_control/job_free.c\ +job_control/job_getprocess.c\ +job_control/job_getrank.c\ +job_control/job_hup_all.c\ +job_control/job_is_completed.c\ +job_control/job_is_stopped.c\ +job_control/job_notify_change.c\ +job_control/job_notify_new.c\ +job_control/job_remove.c\ +job_control/job_run.c\ +job_control/job_update_id.c\ +job_control/job_update_status.c\ +job_control/job_wait.c\ +job_control/jobc_destroy.c\ +job_control/jobc_init.c\ +job_control/mark_job_as_running.c\ +job_control/pprint_brace.c\ +job_control/pprint_case.c\ +job_control/pprint_cmd.c\ +job_control/pprint_for.c\ +job_control/pprint_function.c\ +job_control/pprint_if.c\ +job_control/pprint_subshell.c\ +job_control/pprint_until.c\ +job_control/pprint_while.c\ +job_control/process_cmp_pid.c\ +job_control/process_format.c\ +job_control/process_free.c\ +job_control/put_job_in_background.c\ +job_control/put_job_in_foreground.c\ +job_control/sigchld_handler.c\ +job_control/sigint_handler.c\ +job_control/sigtstp_handler.c\ +job_control/sigttin_handler.c\ +job_control/sigttou_handler.c\ +lexer/do_lexer_routine.c\ +lexer/get_lexer_stack.c\ +lexer/get_lexer_stack2.c\ +lexer/get_reserved_words.c\ +lexer/get_state_global.c\ +lexer/get_state_redir.c\ +lexer/insert_newline.c\ +lexer/isrw_delim.c\ +lexer/keep_last_type.c\ +lexer/lexer_backslash.c\ +lexer/lexer_bquote.c\ +lexer/lexer_curly_braces.c\ +lexer/lexer_default.c\ +lexer/lexer_delim.c\ +lexer/lexer_destroy.c\ +lexer/lexer_dquote.c\ +lexer/lexer_end.c\ +lexer/lexer_great.c\ +lexer/lexer_heredoc.c\ +lexer/lexer_init.c\ +lexer/lexer_less.c\ +lexer/lexer_lex.c\ +lexer/lexer_newline.c\ +lexer/lexer_number.c\ +lexer/lexer_paren.c\ +lexer/lexer_quote.c\ +lexer/lexer_sep.c\ +lexer/lexer_word.c\ +lexer/token_append.c\ +lexer/token_cmp_type.c\ +lexer/token_free.c\ +lexer/token_init.c\ +line_editing/control_features.c\ +line_editing/copy_cut_paste/copy_cut_paste.c\ +line_editing/copy_cut_paste/underline_down.c\ +line_editing/copy_cut_paste/underline_end.c\ +line_editing/copy_cut_paste/underline_function.c\ +line_editing/copy_cut_paste/underline_home.c\ +line_editing/copy_cut_paste/underline_left.c\ +line_editing/copy_cut_paste/underline_reset.c\ +line_editing/copy_cut_paste/underline_right.c\ +line_editing/copy_cut_paste/underline_up.c\ +line_editing/ft_prompt.c\ +line_editing/get_key.c\ +line_editing/init_line/init_history.c\ +line_editing/init_line/init_line.c\ +line_editing/init_line/init_termcaps.c\ +line_editing/lib_line_editing/ft_nb_line.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_term/home_end.c\ +line_editing/move_term/move_left_and_right.c\ +line_editing/move_term/move_to_word.c\ +line_editing/move_term/move_up_and_down.c\ +line_editing/print_del_completion/completion.c\ +line_editing/print_del_completion/print_and_del.c\ +line_editing/print_del_completion/queue.c\ +line_editing/readline.c\ +line_editing/resize.c\ +main/data_exit.c\ +main/data_init.c\ +main/data_singleton.c\ +main/main.c\ +main/shell_fds.c\ +main/shell_init.c\ +main/shell_sig.c\ +parser/add_bang.c\ +parser/add_case.c\ +parser/add_cmd.c\ +parser/add_condition.c\ +parser/add_func.c\ +parser/add_loop.c\ +parser/add_number.c\ +parser/add_redir.c\ +parser/add_sep.c\ +parser/add_subshell.c\ +parser/aggregate_sym.c\ +parser/build_tree.c\ +parser/do_parser_routine.c\ +parser/error_syntax.c\ +parser/eval_sym.c\ +parser/ft_parse.c\ +parser/heredoc_parser.c\ +parser/parser_destroy.c\ +parser/parser_init.c\ +parser/pop_stack.c\ +parser/produce_sym.c\ +parser/push_stack.c\ +parser/redir_init.c\ +parser/stack_init.c\ +parser/sym_free.c\ +parser/tree_func_free.c\ +parser/tree_wrapper.c\ +parser/read_stack.c + +SRCS = $(addprefix $(SRC_DIR), $(SRC_BASE)) +OBJS = $(addprefix $(OBJ_DIR), $(SRC_BASE:.c=.o)) +NB = $(words $(SRC_BASE)) +INDEX = 0 + +all : + @make -C $(LIBFT_DIR) + @make -j $(NAME) + +$(NAME): $(LIBFT_LIB) $(OBJ_DIR) $(OBJS) + @$(CC) $(OBJS) -o $(NAME) \ + -I $(INC_DIR) \ + -I $(LIBFT_INC) \ + $(LIBS) \ + $(LIBFT_LIB) \ + $(FLAGS) $(D_FLAGS) + @strip -x $@ + @printf "\r\033[48;5;15;38;5;25m✅ MAKE $(NAME)\033[0m\033[K\n" + +$(LIBFT_LIB): + @make -C $(LIBFT_DIR) + +$(OBJ_DIR) : + @mkdir -p $(OBJ_DIR) + @mkdir -p $(dir $(OBJS)) + +$(OBJ_DIR)%.o : $(SRC_DIR)%.c | $(OBJ_DIR) + @$(eval DONE=$(shell echo $$(($(INDEX)*20/$(NB))))) + @$(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) $(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) + @printf "\r\033[38;5;202m✖ clean $(NAME).\033[0m\033[K\n" + +cleanlib: + @make -C $(LIBFT_DIR) clean + +fclean: clean fcleanlib + @rm -f $(NAME) + @printf "\r\033[38;5;196m❌ fclean $(NAME).\033[0m\033[K\n" + +fcleanlib: cleanlib + @make -C $(LIBFT_DIR) fclean + +re: fclean all + +relib: fcleanlib $(LIBFT_LIB) + +.PHONY : fclean clean re relib cleanlib fcleanlib + +-include $(OBJS:.o=.d) diff --git a/42sh/README.md b/42sh/README.md new file mode 100644 index 00000000..3eb57cd3 --- /dev/null +++ b/42sh/README.md @@ -0,0 +1,107 @@ +# 42sh + +42sh school project. + +By alao, ariard, gwojda, jhalford, wescande. +Final grade : 125/100 + +More than 10 000 lines of pure C, even the library was written by ourselves. No memory leaks, no crash were allowed. The most impressive project of the first cycle of 42 school cursus. + +Mandatory part: +- Prompt without line edition. +- Builtins `cd`, `echo`, `exit`, `env`, `setenv`, `unsetenv` with there options. +- Executing simple commands with there parameters using `PATH`. +- Support for redirection `>`, `>>`, `<`and `|`. +- Logical operand `&&`and `||`. +- Separator `;`. + +Optional feature (five of theses are mandatory to validate the project): +- Inhibitors `"`, `'`and `\`. +- Advanced redirections: aggregation of file output and heredoc `<<`. +- Globbing: `*`, `?`, `[]`, `{}`, etc. +- Backquotes \`. +- Subshell with operand `()`. +- Local variable and builtin `unset` and `export`. +- History with builtin `history`and `!` with options. +- Advanced line edition. +- File descriptors and builtin `read` with options. +- Dynamical autocompletion. + +Optional feature highly appreciated: +- Job Control and builtins `job`, `fg`, `bg` and operand `&`. +- Shell Scripting in POSIX standards: for, while, until, if/elif/else, {}, bang (!), case, functions, variable assignements + +## Shell / Subshell + +## Line editing + +Keys|Functions| +:-:|:-- +Opt+C
Opt+X
Opt+V|Copy
Cut
Paste +Opt+<
Opt+>|Move per words. +Opt+^
Opt+v|Move per line. +Ctrl+L|Clear screen. +Ctrl+C|Terminate/Kill current foreground process. +Ctrl+Z|Suspend/Stop current foreground process. + +## History + +Keys|Functions| +:-:|:-- +^
v|Browse the history. +Ctrl+R|Research function. +`!!`|Retype the last command. +`!n`|Retype the `n`(numerical value) command from the begin of history. +`!-n`|Retype the `-n`(numerical value) command from the last command. +`!name`|Search for a command beginning with `name`. +`!?name`|Search for a command which contain `name`. + +## Autocompletion + +Autocompletion works with binary, path and env variable. +Output is colored upon type. +Using arrows to navigate is supported. +Autorefreshing with a new input from the user: modification of the list of possibility. + +Commands|Functions| +:-:|:-- +`$> l[tab]`|Search for binary. +`$> ls s[tab]`|Search for path/files. +`$> $[tab]`|Search for variables in `env`. + +## Globbing + +Pattern|Behavior| +:-:|:-- +`*`|Everything. +`**`|Match directory and sub-directory. +`?`|Single char. +`[a-z]`|Match range from `a` to `z`. +`[!a-z]` `[^a-z]`|Exclude range from `a` to `z`. +`{ab, ac}`|Match `ab` or `ac`. + +## Hash table + +Commands|Functions| +:-:|:-- +`hash`|List the content of the hash table. +`hash -r`|Clear the memory of the hash table. + +## Job Control + +Commands|Functions| +:-:|:-- +`jobs`|List all the current running jobs. +`fg`|Bring the most recent process to foreground. +`fg n`|Bring the specified jobs to foreground where `n` is the numerical value of the process found in `jobs`. + +## scripting +`while compound-list ; do compound-list ; done` +`until compound-list ; do compound-list ; done` +`if compound-list ; then compound-list ; elif compound-list ; then compound-list ; else compound-list` +`for i in list ; do compound-list ; done` +`case pattern1 in ( pattern2 ) compound-list ;; ( pattern1) compound-list ;; esac` +`{ compound-list }` +`! command` +`func() { compound-list }` +`VAR="hello world"` diff --git a/42sh/auteur b/42sh/auteur new file mode 100644 index 00000000..e4cd2213 --- /dev/null +++ b/42sh/auteur @@ -0,0 +1,5 @@ +alao +jhalford +ariard +gwojda +wescande diff --git a/42sh/includes/builtin.h b/42sh/includes/builtin.h new file mode 100644 index 00000000..d8894ac3 --- /dev/null +++ b/42sh/includes/builtin.h @@ -0,0 +1,58 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* builtin.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/14 22:59:57 by jhalford #+# #+# */ +/* Updated: 2017/03/25 20:40:22 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef BUILTIN_H +# define BUILTIN_H + +# include "types.h" +# include "libft.h" +# include "builtin_read.h" + +struct s_env_data +{ + t_flag flag; + char **av_data; + char **custom_env; +}; + +typedef struct s_env_data t_env_data; + +t_execf *is_builtin(t_process *p); +int builtin_return_status(int ret, int status); +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 bt_env_opt_u(char *opt_arg, t_env_data *data); +int bt_env_opt_i(char *opt_arg, t_env_data *data); +int builtin_echo(const char *path, char *const argv[], char *const envp[]); +int builtin_cd(const char *path, char *const argv[], char *const envp[]); +int builtin_exit(const char *path, char *const argv[], char *const envp[]); +int builtin_setenv( + const char *path, char *const argv[], char *const envp[]); +int builtin_unsetenv( + const char *path, char *const argv[], char *const envp[]); +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[]); +int builtin_math(const char *path, char *const av[], char *const envp[]); +int builtin_func(const char *path, char *const av[], char *const envp[]); + +int bt_env_geti(char ***av, t_env_data *data); + +void setwd(char *var); +char *bt_cd_get_cdpath(char *arg); +int bt_cd_process_dotdot(char *target); +int bt_cd_process_symlink(char *target); + +#endif diff --git a/42sh/includes/builtin_read.h b/42sh/includes/builtin_read.h new file mode 100644 index 00000000..3362ae89 --- /dev/null +++ b/42sh/includes/builtin_read.h @@ -0,0 +1,59 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* builtin_read.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/20 15:02:39 by jhalford #+# #+# */ +/* Updated: 2017/03/25 04:03:51 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef BUILTIN_READ_H +# define BUILTIN_READ_H + +# define BT_READ_LA (1 << 0) +# define BT_READ_LD (1 << 1) +# define BT_READ_LE (1 << 2) +# define BT_READ_LI (1 << 3) +# define BT_READ_LN (1 << 4) +# define BT_READ_UN (1 << 5) +# define BT_READ_LP (1 << 6) +# define BT_READ_LR (1 << 7) +# define BT_READ_LS (1 << 8) +# define BT_READ_LT (1 << 9) +# define BT_READ_LU (1 << 10) +# define BT_READ_INTER (1 << 11) + +typedef struct s_read t_read; +typedef struct s_readopt t_readopt; + +struct s_read +{ + t_flag flag; + char **names; + char delim; + int nchars; + char *prompt; + int timeout; + int fd; + char *input; +}; + +int builtin_read(const char *path, char *const av[], + char *const envp[]); + +int bt_read_init(t_read *data, char **av); + +struct termios bt_read_term(int init); +int bt_read_terminit(t_read *data); +int bt_read_exit(t_read *data); + +int bt_read_getdelim(char *opt_arg, t_read *data); +int bt_read_getnchars(char *opt_arg, t_read *data); +int bt_read_getprompt(char *opt_arg, t_read *data); +int bt_read_gettimeout(char *opt_argv, t_read *data); +int bt_read_getfd(char *opt_arg, t_read *data); + +#endif diff --git a/42sh/includes/completion.h b/42sh/includes/completion.h new file mode 100644 index 00000000..d37a9653 --- /dev/null +++ b/42sh/includes/completion.h @@ -0,0 +1,199 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* completion.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: alao +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/02/18 11:13:04 by alao #+# #+# */ +/* Updated: 2017/03/28 08:13:56 by alao ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef COMPLETION_H +# define COMPLETION_H + +# include "minishell.h" + +# define KP_U 4283163 +# define KP_D 4348699 +# define KP_L 4479771 +# define KP_R 4414235 +# define KP_T 9 +# define KP_TS 5921563 + +/* +** 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. +** win_y : Size of the window in height. +** m_size : Max size of the list in pagination. +** pos_x : Position of the element relative to the terminal in list mode (X). +** pos_y : Position of the element relative to the terminal in list mode (Y). +** 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 win_y; + int m_size; + int pos_x; + int pos_y; + int key; + int isfolder; + int isrematch; + t_clst *lst; +} t_comp; + +/* +** Main autocompletion engine: +** completion : Main function. +** c_init : Initialization. +** c_matching : Dispatcher for binary or local files. +** c_rematch : Restart on keypress. +** c_glob_matching : Call for globbing completion. +** c_seek_binary : Search binary using env PATH. +** c_seek_files : Solve path and search. +** c_seek_env : Search in env for $(var) +** c_seek_abs_path : Determiner for absolute path +** c_parser : Parser. +** c_add_to_lst : Add new node to the list. +** 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_rematch(t_comp *c, long int keypress); +int c_glob_matching(void); +int c_seek_binary(t_data *s, t_comp *c); +int c_seek_files(t_data *s, t_comp *c, char *current_word); +int c_seek_env(t_comp *c, char *current_word); +void c_seek_abs_path(t_comp *c, char *current_word); +int c_parser(t_comp *c, char *path, char *name); +void c_add_to_lst(t_comp *c, t_clst *node); +int c_sizing(t_comp *c); + +/* +** Output functions: +** +** c_dispatcher : Choose between clear, print or update from to the list +** c_updater : Output the result to struct data. +** c_keypress : Keypress handling. +** c_arrow : Arrow support. +*/ + +int c_dispatcher(t_data *s); +int c_updater(t_comp *c, char *select); +int c_keypress(t_comp *c, long int key); +void c_arrow(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_term_resize : Refresh win_x and win_y. +** 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); +int c_term_resize(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. +** c_exclusion_foldr : Check for match folder. +** ft_sstrlen : Return size of char **. +** ft_sstrtostr : Create char * from char ** with char *sep between. +** ft_add_escape : Add escape char to str. +** c_lst_id : Repair ID list. +** c_is_delim : Check char for specific one. +** c_strdupi : Dupe +*/ + +int c_clear(t_data *s); +int c_clear_lst(t_comp *c); +char *path_solver(t_comp *c, char *cmd, char *cwd); +int c_exclusion_folder(t_comp *c); +int ft_sstrlen(char **s); +char *ft_sstrtostr(char **s, char *sep); +char *ft_add_escape(char *str, char to_escape); +void c_lst_id(t_comp *c); +int c_is_delim(char c); +char *c_strdupi(char *s, int (*f)(char)); + +#endif diff --git a/42sh/includes/exec.h b/42sh/includes/exec.h new file mode 100644 index 00000000..f29b39ba --- /dev/null +++ b/42sh/includes/exec.h @@ -0,0 +1,229 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* exec.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/27 20:29:56 by jhalford #+# #+# */ +/* Updated: 2017/03/29 11:03:30 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef EXEC_H +# define EXEC_H + +# include "types.h" +# include "job_control.h" +# include + +# define IS_PIPESTART(p) ((p).fdin == STDIN) +# define IS_PIPEEND(p) ((p).fdout == STDOUT) +# define IS_PIPESINGLE(p) (IS_PIPESTART(p) && IS_PIPEEND(p)) + +# define EXEC_AND_IF (1 << 0) +# define EXEC_OR_IF (1 << 1) +# define EXEC_IF_BRANCH (1 << 2) +# define EXEC_CASE_BRANCH (1 << 3) + +# define EXEC_AOL_MASK (EXEC_AND_IF | EXEC_OR_IF) + +# define EXEC_IS_BG(j) (j & EXEC_BG) +# define EXEC_IS_FG(j) (!EXEC_IS_BG(j)) +# define EXEC_IS_AND_IF(j) (j & EXEC_AND_IF) +# define EXEC_IS_OR_IF(j) (j & EXEC_OR_IF) +# define EXEC_IS_IF_BRANCH(j) (j & EXEC_IF_BRANCH) +# define EXEC_IS_CASE_BRANCH(j) (j & EXEC_CASE_BRANCH) + +struct s_data_cmd +{ + char **av; + char *path; + t_execf *execf; + struct stat *stat; +}; + +struct s_data_cond +{ + t_btree *condition; + t_btree *content; +}; + +struct s_data_list +{ + t_ld *token; + t_btree *content; +}; + +struct s_data_tree +{ + t_btree *content; +}; + +union u_process_data +{ + struct s_data_cmd cmd; + struct s_data_tree subshell; + struct s_data_tree brace; + struct s_data_tree function; + struct s_data_cond d_while; + struct s_data_cond d_until; + struct s_data_tree d_if; + struct s_data_list d_for; + struct s_data_list d_case; +}; + +enum e_process_state +{ + PROCESS_COMPLETED, + PROCESS_SUSPENDED, + PROCESS_RUNNING, + PROCESS_CONTINUED, +}; + +enum e_process_type +{ + PROCESS_FUNCTION, + PROCESS_BUILTIN, + PROCESS_FILE, + PROCESS_SUBSHELL, + PROCESS_BRACE, + PROCESS_WHILE, + PROCESS_UNTIL, + PROCESS_IF, + PROCESS_FOR, + PROCESS_CASE, + PROCESS_EMPTY, + PROCESS_MAX +}; + +struct s_process_map +{ + int type; + int (*launch)(); + int (*print)(); + int (*free)(); +}; + +struct s_process +{ + t_process_type type; + t_process_data data; + t_process_map map; + t_process_state state; + pid_t pid; + int fdin; + int fdout; + int to_close; + t_list *redirs; + int status; +}; + +struct s_job +{ + int id; + pid_t pgid; + t_flag attrs; + t_list *first_process; + struct termios tmodes; +}; + +struct s_exec +{ + t_job job; + t_flag attrs; + int fdin; + t_list *op_stack; + char **case_pattern; +}; + +int exec_init(t_exec *exec); +int exec_destroy(t_exec *exec); +int process_fork(t_process *p); +int process_setgroup(t_process *p, pid_t pid); +void process_setsig(void); +void process_reset(t_process *p); + +int fd_is_valid(int fd, int flag); +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); + +void set_exitstatus(int status, int override); + +void ast_free(void *data, size_t content_size); +void *node_copy(void *data); +void *redir_copy(void *data); + +void redir_free(void *data, size_t content_size); + +char **token_to_argv(t_ld *ld, int do_match); +t_btree *is_function(t_process *p); + +/* +** Mapping pour free les process +*/ +void process_free(void *content, size_t content_size); +int pfree_cmd(t_process *p); +int pfree_cond(t_process *p); +int pfree_list(t_process *p); +int pfree_subshell(t_process *p); +int pfree_func(t_process *p); + +/* +** Mapping pour launch les process +*/ +int process_launch(t_process *p); +int plaunch_if(t_process *p); +int plaunch_while(t_process *p); +int plaunch_until(t_process *p); +int plaunch_for(t_process *p); +int plaunch_case(t_process *p); +int plaunch_file(t_process *p); +int plaunch_builtin(t_process *p); +int plaunch_subshell(t_process *p); +int plaunch_brace(t_process *p); +int plaunch_function(t_process *p); +int plaunch_empty(t_process *p); + +/* +** Mapping pour set les process +*/ + +int process_set(t_process *p, t_btree *ast); +int pset_map(t_process *p, t_btree *ast); +int pset_cmd(t_process *p, t_btree *ast); +int pset_while(t_process *p, t_btree *ast); +int pset_until(t_process *p, t_btree *ast); +int pset_if(t_process *p, t_btree *ast); +int pset_for(t_process *p, t_btree *ast); +int pset_case(t_process *p, t_btree *ast); +int pset_subshell(t_process *p, t_btree *ast); +int pset_brace(t_process *p, t_btree *ast); + +/* +** Mapping pour exec les process +*/ +int ft_exec(t_btree **ast); +int exec_leaf(t_btree **ast); +int exec_semi(t_btree **ast); +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_elif(t_btree **ast); +int exec_else(t_btree **ast); +int exec_var(t_btree **ast); +int exec_case_branch(t_btree **ast); +int exec_math(t_btree **ast); +int exec_bang(t_btree **ast); +int exec_func(t_btree **ast); + +#endif diff --git a/42sh/includes/ft_curs.h b/42sh/includes/ft_curs.h new file mode 100644 index 00000000..8d0bf2eb --- /dev/null +++ b/42sh/includes/ft_curs.h @@ -0,0 +1,84 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_curs.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: sbenning +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/08 16:34:51 by sbenning #+# #+# */ +/* Updated: 2017/03/23 00:03:16 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef FT_CURS_H +# define FT_CURS_H + +# include "libft.h" + +# include +# include +# include +# include +# include + +typedef struct s_curs t_curs; + +/* +** Cursor data : cursor's coordonate and windows size +*/ + +struct s_curs +{ + int co; + int li; + int win_co; + int win_li; +}; + +/* +** Cursor reference singleton +*/ + +t_curs *curs_single(t_curs *curs, int set); + +/* +** Cursor setup +*/ + +int curs_li_ask(void); +int curs_co_ask(void); + +int curs_term_setup(void); +void curs_win_setup(t_curs *curs); +int curs_coo_setup(t_curs *curs); +int curs_setup(t_curs *curs); + +/* +** Cursor cleanup +*/ + +int curs_term_cleanup(void); +int curs_cleanup(t_curs *curs); + +/* +** Cursor's data reset +*/ + +void curs_reset(int sig); + +/* +** Cursor manipulation function +*/ + +void curs_clear(t_curs *curs); +void curs_clear_post(t_curs *curs); +void curs_goto(t_curs *curs, int li, int co); +void curs_forward(t_curs *curs, int offset); +void curs_backward(t_curs *curs, int offset); +void curs_write(t_curs *curs, char *str, size_t len); +void curs_write_static(t_curs *curs, char *str, size_t len); +void curs_video_write(t_curs *curs, char *str, size_t len); +void curs_video_write_static( + t_curs *curs, char *str, size_t len); + +#endif diff --git a/42sh/includes/ft_readline.h b/42sh/includes/ft_readline.h new file mode 100644 index 00000000..c3dbf5e6 --- /dev/null +++ b/42sh/includes/ft_readline.h @@ -0,0 +1,190 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_readline.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/23 10:35:44 by gwojda #+# #+# */ +/* Updated: 2017/03/29 17:41:14 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef FT_READLINE_H +# define FT_READLINE_H + +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include + +# define FLECHE_HAUT 4283163 +# define FLECHE_BAS 4348699 +# define FLECHE_GAUCHE 4479771 +# define FLECHE_DROITE 4414235 +# define TOUCHE_DELETE 2117294875 +# define TOUCHE_CTRL_C 3 +# define TOUCHE_CTRL_D 4 +# define TOUCHE_CTRL_L 12 +# define TOUCHE_CTRL_R 18 +# define TOUCHE_SUPPR 127 +# define TOUCHE_HOME 4741915 +# define TOUCHE_END 4610843 +# define TOUCHE_TAB 9 +# define TOUCHE_OPT_RIGHT 1130044187 +# define TOUCHE_OPT_LEFT 1146821403 +# define TOUCHE_OPT_UP 1096489755 +# define TOUCHE_OPT_DOWN 1113266971 +# define TOUCHE_OPT_V 10127586 +# define TOUCHE_OPT_C 42947 +# define TOUCHE_OPT_X 8948194 +# define TOUCHE_F5 892427035 +# define TOUCHE_F6 925981467 + +# define SIZE_LINE 16384 + +# define CORRUPT 1 + +# define ERROR_CNTL_R 1 + +typedef struct s_list_history +{ + char *str; + struct s_list_history *prev; + struct s_list_history *next; +} t_list_history; + +typedef struct s_line +{ + int fd; + char *input; + size_t pos; + char *copy_tmp; + size_t pos_tmp; + int prompt_size; + int list_size; + char opt; + char is_prompt; + t_list_history *list_end; + t_list_history *list_cur; + t_list_history *list_beg; +} t_line; + +typedef struct s_key +{ + int value; + int (*f)(char **str, size_t *pos); +} t_key; + +typedef struct s_cpy +{ + int value; + int (*f)(char **str, size_t *pos, size_t pos_ref); +} t_cpy; + +extern t_key g_keys[]; +extern t_cpy g_cpy[]; + +void ft_reset_tab(char *tabl); +void ft_putnc(char c, int n); +int ft_nbr_len(int nbr); +void ft_puttermcaps(char *str); +void ft_get_beggin_with_curs(char *str, size_t *pos); +void ft_check_end_of_line(char *str, size_t pos); +int ft_size_term(void); +void ft_add_in_history_file(char *str); +void ft_get_beggin(char *str, size_t *pos); +void ft_get_next_str(char *str, size_t *pos); +void ft_putall_current_str(char *str, size_t *pos); +void ft_current_str(char *str, size_t pos); +int ft_strlen_next(char *str, size_t pos); +void ft_push_back_history( + t_list_history **head, t_list_history *new); +void ft_prompt(void); +char *ft_remove_imput(char *str, size_t pos); +char *ft_realloc_imput(char *str, int a, size_t pos); +char *ft_strdupi(char const *s); +char *ft_strndup(char const *s, int n); +t_list_history *ft_create_history_list(char *str); +char *ft_strdupi_w(char const *s); +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); +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); +void ft_clear_window(void); +void free_history_list(t_list_history *head); +int ft_nb_of_line(char *str, size_t pos); +int ft_get_size_prev(char *str, size_t pos); +void sigwinch_resize(int sig); +size_t ft_hist_len(void); +int hist_is_delim(char c); +int ft_nb_last_line(char *str, size_t pos); + +int underline_right(char **str, size_t *pos, size_t pos_ref); +int underline_left(char **str, size_t *pos, size_t pos_ref); +int underline_home(char **str, size_t *pos, size_t pos_ref); +int underline_end(char **str, size_t *pos, size_t pos_ref); +int underline_down(char **str, size_t *pos, size_t pos_ref); +int underline_up(char **str, size_t *pos, size_t pos_ref); +void underline_check_end_of_line(char *str, size_t pos); +void reset_term(char **str, size_t *pos); +void reset_and_remove_term(char **str, size_t *pos, char *copy_tmp); + +int ft_read_stdin(char **input); + +int ft_end(char **str, size_t *pos); +int ft_home(char **str, size_t *pos); +int ft_move_right(char **str, size_t *pos); +int ft_move_left(char **str, size_t *pos); +int ft_up(char **str, size_t *pos); +int ft_down(char **str, size_t *pos); +int ft_buff_f6(char **str, size_t *pos); +int ft_control_d(char **str, size_t *pos); +int ft_control_c(char **str, size_t *pos); +int ft_control_l(char **str, size_t *pos); +int ft_del(char **str, size_t *pos); +int ft_suppr(char **str, size_t *pos); +int ft_surch_in_history(char **str, size_t *pos); +int ft_printall(char **str, size_t *pos); +int ft_history_down(char **str, size_t *pos); +int ft_history_up(char **str, size_t *pos); +int ft_found_next_word(char **str, size_t *pos); +int ft_found_prev_word(char **str, size_t *pos); +int ft_c(char **str, size_t *pos); +int ft_x(char **str, size_t *pos); +int ft_v(char **str, size_t *pos); +int ft_read_it(int input, size_t *pos, char **str); +int ft_print(int ret, char **str, size_t *pos); + +int readline(int prompt, char **input); +int ft_completion(int ret, char **str, size_t *pos); + +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); +int ft_history_parsing(int has_prompt, char **input); +struct termios *ft_save_termios(int save); +void ft_init_termios(void); +void readline_init(int prompt); + +#endif diff --git a/42sh/includes/glob.h b/42sh/includes/glob.h new file mode 100644 index 00000000..bbd691b9 --- /dev/null +++ b/42sh/includes/glob.h @@ -0,0 +1,106 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* glob.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/04 16:31:18 by wescande #+# #+# */ +/* Updated: 2017/03/25 03:22:10 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef GLOB_H +# define GLOB_H + +# 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 +{ + void *content; + struct s_ld *next; + struct s_ld *prev; +} t_ld; + +typedef struct s_glob +{ + short int found; + short int cur_dir; + char *pat; + unsigned char *esc; + unsigned char *esc2; + t_ld *match; + t_ld *match_tmp; + t_ld *m_pat; +} t_glob; + +typedef struct s_expand +{ + t_ld **wk; + char *str; + unsigned char *esc; + char **split; + unsigned char **m_esc; + 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(char *str, unsigned char *esc, + unsigned char *dbl_esc, int do_match); +void esc_print(int fd, char *str, unsigned char *esc); +int word_is_assignment(char **content); +void *tab_esc_copy(void *content); +char *get_output(char *command); + +/* +** 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); +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_home(t_glob *gl, char *str); +void expand_var(t_glob *tglob); +void expand_home(t_glob *gl, char *str); +int match_pattern(t_glob *tglob, char *str, char *full_word); +int dir_research(t_glob *tglob, char *p, char *pat, int *mode); +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, + const unsigned char *esc, char c); + +#endif diff --git a/42sh/includes/hash.h b/42sh/includes/hash.h new file mode 100644 index 00000000..e9a27aac --- /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/03/19 16:37:44 by wescande ### ########.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; + +char *ft_add_hash(char *cmd); +char *ft_hash(char *cmd); +char *ft_is_hash(char *cmd); +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/job_control.h b/42sh/includes/job_control.h new file mode 100644 index 00000000..26262861 --- /dev/null +++ b/42sh/includes/job_control.h @@ -0,0 +1,97 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* job_control.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/10 16:55:09 by jhalford #+# #+# */ +/* Updated: 2017/03/27 16:01:12 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef JOB_CONTROL_H +# define JOB_CONTROL_H + +# include +# include +# include +# include "types.h" +# include "exec.h" + +# define JOB_NOTIFIED (1 << 0) +# define JOB_BG (1 << 1) + +# define JOB_IS_BG(j) (j & JOB_BG) +# define JOB_IS_FG(j) (!JOB_IS_BG(j)) + +# define JOBS_OPT_L (1 << 0) + +struct s_jobc +{ + t_list *first_job; + pid_t shell_pgid; + int current_id; + struct termios shell_tmodes; +}; + +int jobc_init(t_jobc *jobc); +int jobc_destroy(t_jobc *jobc); + +t_list *job_getprocess(pid_t pid); +int job_addprocess(t_process *p); +void job_update_id(void); +void job_update_rank(void); + +int do_job_notification(void); +void job_notify_new(int id); +void job_format(t_job *j, int opts); +void job_format_head(t_job *j); + +void job_update_status(void); +void mark_job_as_running (t_job *j); +int mark_process_status(pid_t pid, int status); +int job_is_stopped(t_job *job); +int job_is_completed(t_job *job); +int has_running_job(void); +int has_stopped_job(void); + +void job_new(char **av, pid_t pid); +void job_run(t_job *job, int foreground); +int job_wait(int id); +void job_remove(int id); +void job_free(void *content, size_t content_size); +void job_hup_all(void); + +int put_job_in_foreground(t_job *job, int cont); +int put_job_in_background(t_job *job, int cont); + +int job_cmp_pid(t_job *job, pid_t *pid); +int job_cmp_id(t_job *job, int *id); +void job_getrank(int (*rank)[2]); + +void sigchld_handler(int signo); +void sigint_handler(int signo); +void sigtstp_handler(int signo); +void sigttin_handler(int signo); +void sigttou_handler(int signo); + +int process_cmp_pid(t_process *p, pid_t *pid); +void process_format(t_list **p, int firstp, int opts); + +/* +** Mapping pour afficher les process +*/ + +void pprint(t_process *p); +int pprint_subshell(t_process *p); +int pprint_brace(t_process *p); +int pprint_while(t_process *p); +int pprint_if(t_process *p); +int pprint_case(t_process *p); +int pprint_until(t_process *p); +int pprint_function(t_process *p); +int pprint_for(t_process *p); +int pprint_cmd(t_process *p); + +#endif diff --git a/42sh/includes/lexer.h b/42sh/includes/lexer.h new file mode 100644 index 00000000..4a260e26 --- /dev/null +++ b/42sh/includes/lexer.h @@ -0,0 +1,119 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* lexer.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/01 12:15:50 by jhalford #+# #+# */ +/* Updated: 2017/03/27 19:19:22 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef LEXER_H +# define LEXER_H + +# include "minishell.h" +# include "libft.h" +# include "types.h" + +enum e_lexstate +{ + DEFAULT, + PAREN, + HEREDOC, + NEWLINE, + DELIM, + SEP, + WORD, + NUMBER, + LESS, + GREAT, + QUOTE, + DQUOTE, + BQUOTE, + BACKSLASH, + CURLY_BRACKETS, + END, +}; + +struct s_token +{ + t_type type; + char *data; + unsigned char *esc; + unsigned char *esc2; + int size; +}; + +struct s_lexer +{ + char *str; + int pos; + t_lexstate state; + t_list *stack; + t_list *heredoc_stack; +}; + +struct s_rvwords +{ + char *word; + int type; +}; + +int ft_post_tokenize(t_list **alst, char **str); + +t_token *token_init(); +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); + +int reduce_parens(t_list **alst, char *str); +int bquotes_expand(t_list **alst); +char *command_getoutput(char *command); + +int ft_is_delim(char c); +int ft_is_delim_list(char c); + +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); +int get_lexer_stack2(t_lexer lexer); +int get_reserved_words(t_list *temp); +int isrw_delim(t_type type); +int keep_last_type(t_type *type, t_list *token); +int insert_newline(t_list **alst); + +int do_lexer_routine(t_list **token, char *stream); +void lexer_init(t_lexer *lexer); +void lexer_destroy(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_heredoc(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_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_curly_braces(t_list **alst, t_lexer *lexer); +int lexer_assignement_word(t_list **alst, t_lexer *lexer); +int lexer_comment(t_list **alst, t_lexer *lexer); +int lexer_end(t_list **alst, t_lexer *lexer); + +#endif diff --git a/42sh/includes/minishell.h b/42sh/includes/minishell.h new file mode 100644 index 00000000..0b755490 --- /dev/null +++ b/42sh/includes/minishell.h @@ -0,0 +1,80 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* minishell.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/10 13:07:44 by jhalford #+# #+# */ +/* Updated: 2017/03/27 15:55:04 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef MINISHELL_H +# define MINISHELL_H + +# define SHELL_NAME "minishell" + +# include +# include +# include +# include +# include +# include + +# include "../libft/includes/libft.h" +# include "types.h" +# include "lexer.h" +# include "parser.h" +# include "ft_readline.h" +# include "job_control.h" +# include "exec.h" +# include "builtin.h" +# include "glob.h" +# include "completion.h" +# include "hash.h" + +# define SH_MSG(s, ...) "{red}%s: " s "{eoc}\n", g_argv[0], ##__VA_ARGS__ +# define SH_ERR(s, ...) ft_dprintf(STDERR, SH_MSG(s, ##__VA_ARGS__)) + +struct s_data +{ + t_flag opts; + char **av_data; + char *c_arg; + int fd; + char **env; + int argc; + char **argv; + t_line line; + t_lexer lexer; + t_list *fd_save[10]; + t_parser parser; + t_comp *comp; + t_exec exec; + t_jobc jobc; + char **local_var; + t_list *lst_func; + char *binary; +}; + +t_data *data_singleton(); +int shell_init(int ac, char **av, char **env); +void shell_exit(void); +int data_init(int ac, char **av, char **env); +void data_exit(void); +int get_c_arg(char *opt_arg, t_data *data); + +void shell_sig_reset(void); + +void shell_fds_init(void); +void shell_fds_destroy(void); +int shell_fds_pop(void); +int shell_fds_push(void); +void shell_fds_reset(void); +void shell_fds_destroy(void); + +char *ft_putast(void *node); +void ft_putast2(void *node); + +#endif diff --git a/42sh/includes/parser.h b/42sh/includes/parser.h new file mode 100644 index 00000000..d0d0cb76 --- /dev/null +++ b/42sh/includes/parser.h @@ -0,0 +1,182 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* parser.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ariard +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/22 17:22:51 by ariard #+# #+# */ +/* Updated: 2017/03/29 17:01:08 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef PARSER_H +# define PARSER_H + +/* +** Parse POSIX grammar +*/ + +enum e_parstate +{ + ERROR = 0, + UNDEFINED, + SUCCESS, +}; + +# define MATCH_STACK(x, y) (x == y || y == ALL) + +struct s_parser +{ + t_parstate state; + t_list *stack; + t_sym *new_sym; + t_list *heredoc_queue; + int cache; +}; + +struct s_aggrematch +{ + t_sym top; + t_sym under; + t_sym new_sym; + int erase_sym; +}; + +struct s_prodmatch +{ + t_type token; + t_sym stack; + t_sym new_sym; +}; + +struct s_stackmatch +{ + t_sym top; + t_sym under; +}; + +struct s_errormatch +{ + t_type token; + char *error; +}; + +int do_parser_routine(t_list **token, t_btree **ast); +void parser_init(t_parser *parser); +void parser_destroy(t_parser *parser); +int stack_init(t_parser *parser); +int redir_init(t_type type, t_redir *redir); +int ft_parse(t_btree **ast, t_list **token, t_parser *parser); + +int produce_sym(t_list **stack, t_sym *new_sym, t_list **lst); +int eval_sym(t_list **stack, t_sym new_sym); +int aggregate_sym(t_list **stack, t_sym *new_sym, t_parstate *state); + +int push_stack(t_list **stack, t_sym new_sym); +int pop_stack(t_list **stack, t_sym erase_sym); + +int pop_heredoc(t_list **lst); + +int error_syntax(t_list **token); +int error_eof(void); + +int ft_read_stack(t_sym *stack); +char *read_state(t_sym current); + +struct s_treematch +{ + t_type type; + int (*add)(t_btree **ast, t_list **lst); +}; + +int build_tree(t_btree **ast, t_list **lst, t_parser *parser); + +int add_sep(t_btree **ast, t_list **lst); +int add_cmd(t_btree **ast, t_list **lst); + +int add_file(t_btree **ast, t_list **lst); +int add_loop_cmd(t_btree **ast, t_list **lst); +int add_loop_sep(t_btree **ast, t_list **lst); +int add_condition_cmd(t_btree **ast, t_list **lst); +int add_condition_sep(t_btree **ast, t_list **lst); +int add_branch(t_btree **ast, t_list **lst); +int add_redir_word(t_btree **ast, t_list **lst); +int add_redir_type(t_btree **ast, t_list **lst); +int redir_init(t_type type, t_redir *redir); +int add_case_cmd(t_btree **ast, t_list **lst); +int add_case_sep(t_btree **ast, t_list **lst); +int add_pattern(t_btree **ast, t_list **lst); +int add_subshell_cmd(t_btree **ast, t_list **lst); +int add_subshell_sep(t_btree **ast, t_list **lst); +int add_func_cmd(t_btree **ast, t_list **lst); +int add_one_func(t_btree **ast, t_list **lst); +int add_pipe(t_btree **ast, t_list **lst); +int add_null(t_btree **ast, t_list **lst); +int add_ionumber(t_btree **ast, t_list **lst); +int add_bang(t_btree **ast, t_list **lst); +int add_bang_sep(t_btree **ast, t_list **lst); +int add_if(t_btree **ast, t_list **lst); + +int isloop(t_btree **ast, t_list **lst); +int iscase(t_btree **ast, t_list **lst); +int iscase_pattern(t_btree **ast, t_list **lst); +int iscase_branch(t_btree **ast, t_list **lst); +int iscondition(t_btree **ast, t_list **lst); +int iscondition_branch(t_btree **ast, t_list **lst); +int issubshell(t_btree **ast, t_list **lst); +int isfunc(t_btree **ast, t_list **lst); +int isfunc_name(t_btree **ast, t_list **lst); +int isdir(t_btree **ast); +int iscondition(t_btree **ast, t_list **list); +int isdir_sep(t_btree **ast, t_list **list); +int isdir_word(t_btree **ast, t_list **list); +int isnull(t_btree **ast, t_list **list); +int isionumber(t_btree **ast, t_list **lst); +int isbang(t_btree **ast, t_list **lst); +int isbang_sep(t_btree **ast, t_list **lst); + +int join_ast(t_btree **ast, t_btree **new_node); +int gen_node(t_btree **ast); +int superflous_token(t_btree **ast, t_list **list); +void sym_free(void *data, size_t size); +void tree_func_free(void *data, size_t content_size); + +char *read_state(t_sym current); + +struct s_distrostree +{ + int (*test)(t_btree **ast, t_list **lst); + int (*add)(t_btree **ast, t_list **lst); +}; + +struct s_redir +{ + t_type type; + int n; + char *word; + char *heredoc_data; +}; + +struct s_cmd +{ + t_list *redir; + t_ld *token; +}; + +union u_astdata +{ + t_cmd cmd; +}; + +struct s_astnode +{ + int pattern; + int nest; + int full; + int cache; + t_type type; + t_astdata data; +}; + +#endif diff --git a/42sh/includes/types.h b/42sh/includes/types.h new file mode 100644 index 00000000..bc69aa24 --- /dev/null +++ b/42sh/includes/types.h @@ -0,0 +1,235 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* types.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/13 17:11:48 by jhalford #+# #+# */ +/* Updated: 2017/03/29 16:40:25 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef TYPES_H +# define TYPES_H + +# include + +# 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 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 SH_NO_INTERACTIVE(b) !(b & SH_INTERACTIVE) + +# define SH_MSG_NOJOBC "no job-control" + +typedef long long t_type; +typedef long long t_flag; + +typedef struct s_data t_data; +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 struct s_lexer t_lexer; +typedef struct s_parser t_parser; +typedef enum e_mode t_mode; +typedef struct s_data_template t_btexport; + +/* +** Lexer types +*/ + +typedef enum e_lexstate t_lexstate; +typedef struct s_token t_token; +typedef struct s_rvwords t_rvwords; +typedef struct s_ld t_ld; + +/* +** Execution types +*/ + +typedef int t_condition; +typedef struct s_job t_job; +typedef struct s_process t_process; +typedef int (t_execf)(const char *path, + char *const argv[], + char *const envp[]); +typedef enum e_process_type t_process_type; +typedef enum e_process_state t_process_state; +typedef union u_process_data t_process_data; +typedef struct s_process_map t_process_map; +typedef struct s_data_cond t_data_while; +typedef struct s_data_cond t_data_if; + +/* +** Parser types +*/ + +typedef struct s_astnode t_astnode; +typedef struct s_redir t_redir; +typedef struct s_cmd t_cmd; +typedef union u_astdata t_astdata; +typedef union u_word t_word; +typedef int t_sym; +typedef enum e_parstate t_parstate; +typedef struct s_aggrematch t_aggrematch; +typedef struct s_prodmatch t_prodmatch; +typedef struct s_stackmatch t_stackmatch; +typedef struct s_errormatch t_errormatch; +typedef struct s_treematch t_treematch; +typedef struct s_distrostree t_distrostree; + +enum e_sym +{ + LINEBREAK = 1, + TK_COMMAND, + TK_LESS, + TK_GREAT, + TK_DLESS, + TK_DGREAT, + TK_LESSAND, + TK_GREATAND, + TK_SEMI, + TK_PIPE, + TK_AND_IF, + TK_OR_IF, + TK_AMP, + TK_PAREN_OPEN, + TK_PAREN_CLOSE, + TK_BQUOTE, + TK_NEWLINE, + TK_WHILE, + TK_DO, + TK_DONE, + TK_IF, + TK_THEN, + TK_FI, + TK_ELIF, + TK_ELSE, + TK_UNTIL, + TK_WORD, + TK_ASSIGNMENT_WORD = 50, + TK_BANG, + TK_NAME, + TK_FOR, + TK_IO_NUMBER, + TK_DLESSDASH, + TK_LESSGREAT, + TK_CASE, + TK_IN, + TK_ESAC, + TK_CLOBBER, + TK_LBRACE, + TK_RBRACE, + TK_DSEMI, + PROGRAM = 100, + COMPLETE_COMMAND, + COMPLETE_COMMANDS, + LIST, + AND_OR, + PIPELINE, + PIPE_SEQUENCE, + COMMAND, + COMPOUND_COMMAND, + SUBSHELL, + COMPOUND_LIST, + TERM, + FOR_CLAUSE, + NAME, + IN, + WORDLIST, + CASE_CLAUSE, + CASE_LIST, + CASE_LIST_NS, + CASE_ITEM, + CASE_ITEM_NS, + PATTERN, + IF_CLAUSE, + BRACE_CLAUSE, + ELSE_PART, + WHILE_CLAUSE, + UNTIL_CLAUSE, + FUNCTION_DEFINITION, + FUNCTION_BODY, + FNAME, + BRACE_GROUP, + DO_GROUP, + SIMPLE_COMMAND, + CMD_NAME, + CMD_WORD, + CMD_PREFIX, + CMD_SUFFIX, + REDIRECT_LIST, + IO_REDIRECT, + IO_FILE, + FILENAME, + IO_HERE, + HERE_END, + NEWLINE_LIST, + SEPARATOR_OP, + SEPARATOR, + SEQUENTIAL_SEP, + BRACE, + LOOP, + FUNC, + PIPE_SEMI_SEQUENCE, + PIPE_CLOSE_SEQUENCE, + CMD_SUPERIOR, + SEQUENCE, + END_COMMAND, + CONDITION, + COMPLETE_CONDITION, + FOR_WORDLIST, + PATTERN_CASE, + FUNC_NAME, + OPEN_FUNC, + CLOSE_FUNC, + CLOSE_LIST, + OTHER, + REDIR, + CMD, + AND_OR_MAJOR, + AND_OR_MINOR, + HEREDOCDATA, + HEREDOC_DELIM, + ALL = 200, + TERMINUS = 300, +}; + +/* +** LIST D: +*/ + +void ft_ld_new(t_ld **alst, void *content); +t_ld *ft_ld_front(t_ld *ld); +void ft_ld_pushfront(t_ld **alst, void *content); +void ft_ld_pushback(t_ld **alst, void *content); +size_t ft_ld_size(t_ld *ld); +void ft_ld_del(t_ld **ld, void (*del)()); +void ft_ld_clear(t_ld **ld, void (*del)()); +void ft_ld_reverse(t_ld **lst); +t_ld *ft_ld_back(t_ld *ld); +t_ld *ft_ld_swap(t_ld *l_cur); +char **ft_ld_to_tab(t_ld *ld); +t_ld *ft_ld_order(t_ld *ld, int (*f)()); +t_ld *ft_ld_copy(t_ld *src, void *(*f)(void *elem)); + +/* +** str: +*/ + +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/libft/.gitignore b/42sh/libft/.gitignore new file mode 100644 index 00000000..75a55b30 --- /dev/null +++ b/42sh/libft/.gitignore @@ -0,0 +1 @@ +libft.a diff --git a/42sh/libft/Makefile b/42sh/libft/Makefile new file mode 100644 index 00000000..097f38e0 --- /dev/null +++ b/42sh/libft/Makefile @@ -0,0 +1,246 @@ +# **************************************************************************** # +# # +# ::: :::::::: # +# Makefile :+: :+: :+: # +# +:+ +:+ +:+ # +# By: jhalford +#+ +:+ +#+ # +# +#+#+#+#+#+ +#+ # +# Created: 2017/02/07 16:09:36 by jhalford #+# #+# # +# Updated: 2017/03/29 11:08:06 by gwojda ### ########.fr # +# # +# **************************************************************************** # + +NAME = libft.a + +CC = gcc +AR = ar -rc +MKDIR = mkdir -p +RM = /bin/rm -rf + +W_FLAGS = -Wall -Wextra -Werror -g +D_FLAGS = -g +FLAGS = $(W_FLAGS) $(D_FLAGS) + +DELTA = $$(echo "$$(tput cols)-47"|bc) + +SRC_DIR = src/ +INC_DIR = includes/ +OBJ_DIR = objs/ + +SRC_BASE = \ +btree/btree_apply_by_level.c\ +btree/btree_apply_infix.c\ +btree/btree_apply_prefix.c\ +btree/btree_apply_suffix.c\ +btree/btree_create_node.c\ +btree/btree_del.c\ +btree/btree_delone.c\ +btree/btree_insert_data.c\ +btree/btree_level_count.c\ +btree/btree_map.c\ +btree/btree_print.c\ +btree/btree_search_item.c\ +char/ft_isalnum.c\ +char/ft_isalpha.c\ +char/ft_isascii.c\ +char/ft_isdigit.c\ +char/ft_isprint.c\ +char/ft_tolower.c\ +char/ft_toupper.c\ +cliopts/cliopts_get.c\ +cliopts/cliopts_getmap.c\ +color/ft_color_mk.c\ +color/ft_color_mkif.c\ +color/ft_color_reset.c\ +color/ft_color_set.c\ +dlst/ft_dlstadd_after.c\ +dlst/ft_dlstadd_before.c\ +dlst/ft_dlstdel.c\ +dlst/ft_dlstdelone.c\ +dlst/ft_dlstlast.c\ +dlst/ft_dlstnew.c\ +dlst/ft_dlstrtostr.c\ +dlst/ft_dlstsize.c\ +error/error.c\ +ft_printf/ft_conversion.c\ +ft_printf/ft_fmt_simplify.c\ +ft_printf/ft_fmt_validate_conv.c\ +ft_printf/ft_fmt_validate_flags.c\ +ft_printf/ft_fmt_validate_mod.c\ +ft_printf/ft_printf.c\ +ft_printf/ft_printf_color.c\ +ft_printf/ft_printf_parse.c\ +ft_printf/ft_transform.c\ +ft_printf/ft_vprintf.c\ +ft_printf/lib_fmt.c\ +ft_printf/lib_fmt_error.c\ +ft_printf/lib_pad.c\ +ft_printf/lib_pad_sharp.c\ +get_next_line/get_next_line.c\ +lst/ft_id.c\ +lst/ft_lst_at.c\ +lst/ft_lst_bfree.c\ +lst/ft_lst_cfree.c\ +lst/ft_lst_delif.c\ +lst/ft_lst_delsub.c\ +lst/ft_lst_filter.c\ +lst/ft_lst_find.c\ +lst/ft_lst_merge.c\ +lst/ft_lst_order_delsub.c\ +lst/ft_lst_print.c\ +lst/ft_lst_print2.c\ +lst/ft_lst_removeif.c\ +lst/ft_lst_reverse.c\ +lst/ft_lst_size.c\ +lst/ft_lst_sorted_insert.c\ +lst/ft_lst_sorted_merge.c\ +lst/ft_lstadd.c\ +lst/ft_lstdel.c\ +lst/ft_lstdelone.c\ +lst/ft_lsteadd.c\ +lst/ft_lstiter.c\ +lst/ft_lstlast.c\ +lst/ft_lstmap.c\ +lst/ft_lstnadd.c\ +lst/ft_lstnew.c\ +lst/ft_lstnew_range.c\ +lst/ft_lstsort.c\ +lst/pop.c\ +lst/push.c\ +lst/top.c\ +math/ft_addrcmp.c\ +math/ft_ilen.c\ +math/ft_ilen_base.c\ +math/ft_itoa.c\ +math/ft_itoa_base.c\ +math/ft_lllen.c\ +math/ft_lllen_base.c\ +math/ft_lltoa_base.c\ +math/ft_uilen.c\ +math/ft_uitoa_base.c\ +math/ft_ulltoa_base.c\ +math/id.c\ +mem/ft_bzero.c\ +mem/ft_malloc.c\ +mem/ft_memalloc.c\ +mem/ft_memccpy.c\ +mem/ft_memchr.c\ +mem/ft_memcmp.c\ +mem/ft_memcpy.c\ +mem/ft_memdel.c\ +mem/ft_memmove.c\ +mem/ft_memset.c\ +mem/ft_realloc.c\ +path/ft_path_notdir.c\ +printing/ft_putchar.c\ +printing/ft_putendl.c\ +printing/ft_putnbr.c\ +printing/ft_putstr.c\ +sstr/ft_sstradd.c\ +sstr/ft_sstrcat.c\ +sstr/ft_sstrdel.c\ +sstr/ft_sstrdup.c\ +sstr/ft_sstrfree.c\ +sstr/ft_sstrmerge.c\ +sstr/ft_sstrprint.c\ +sstr/ft_sstrprint_fd.c\ +sstr/ft_sstrsort.c\ +sstr/ft_sstrstr.c\ +str/ft_atoi.c\ +str/ft_convert_base.c\ +str/ft_putaddr_fd.c\ +str/ft_split_whitespaces.c\ +str/ft_str3join.c\ +str/ft_strappend.c\ +str/ft_strbetween.c\ +str/ft_strcat.c\ +str/ft_strcatf.c\ +str/ft_strchr.c\ +str/ft_strchrcpy.c\ +str/ft_strclr.c\ +str/ft_strcmp.c\ +str/ft_strcpy.c\ +str/ft_strcspn.c\ +str/ft_strcut.c\ +str/ft_strdel.c\ +str/ft_strdup.c\ +str/ft_strdupchr.c\ +str/ft_strduptr.c\ +str/ft_strequ.c\ +str/ft_strinsert.c\ +str/ft_stris.c\ +str/ft_striter.c\ +str/ft_striteri.c\ +str/ft_strjoin.c\ +str/ft_strlcat.c\ +str/ft_strlen.c\ +str/ft_strlenchr.c\ +str/ft_strmap.c\ +str/ft_strmapi.c\ +str/ft_strncat.c\ +str/ft_strncmp.c\ +str/ft_strncpy.c\ +str/ft_strnequ.c\ +str/ft_strnew.c\ +str/ft_strnstr.c\ +str/ft_strrchr.c\ +str/ft_strreplace.c\ +str/ft_strrev.c\ +str/ft_strsplit.c\ +str/ft_strstr.c\ +str/ft_strsub.c\ +str/ft_strtok.c\ +str/ft_strtrim.c\ +sys/create_directory.c\ +sys/dup2_close.c\ +sys/fd_replace.c\ +sys/ft_getenv.c\ +sys/ft_xattr_count.c\ +sys/ft_xattr_print.c\ +sys/is_directory.c\ +sys/try_access.c\ +time/ft_mytime_free.c\ +time/ft_mytime_get.c\ +time/ft_time_isrecent.c + +SRCS = $(addprefix $(SRC_DIR), $(SRC_BASE)) +OBJS = $(addprefix $(OBJ_DIR), $(SRC_BASE:.c=.o)) +NB = $(words $(SRC_BASE)) +INDEX = 0 + +all: + @make -j $(NAME) + +$(NAME): $(OBJ_DIR) $(OBJS) + @$(AR) $(NAME) $(OBJS) + @ranlib $(NAME) + @# @strip -x $(NAME) + @printf "\r\033[48;5;15;38;5;25m✅ MAKE $(NAME)\033[0m\033[K\n" + +$(OBJ_DIR)%.o: $(SRC_DIR)%.c | $(OBJ_DIR) + @$(eval DONE=$(shell echo $$(($(INDEX)*20/$(NB))))) + @$(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) $(DELTA) "$@" + @$(CC) $(FLAGS) -MMD -c $< -o $@\ + -I $(INC_DIR) + @$(eval INDEX=$(shell echo $$(($(INDEX)+1)))) + +$(OBJ_DIR): + @$(MKDIR) $(OBJ_DIR) + @$(MKDIR) $(dir $(OBJS)) + +clean: + @$(RM) $(OBJ_DIR) + @printf "\r\033[38;5;202m✖ clean $(NAME).\033[0m\033[K\n" + +fclean: clean + @$(RM) $(NAME) + @printf "\r\033[38;5;196m❌ fclean $(NAME).\033[0m\033[K\n" + +re: fclean all + +.PHONY: all clean fclean re + +-include $(OBJS:.o=.d) diff --git a/42sh/libft/README.md b/42sh/libft/README.md new file mode 100644 index 00000000..aaf37755 --- /dev/null +++ b/42sh/libft/README.md @@ -0,0 +1,22 @@ +# libft + +## libc + +malloc interface functions, string manipulation + +## data structures + +- string anipulation (`char *`) +- string array manipulation (`char **`) +- linked list (`t_list`) +- double linked list (`t_dlist`) +- binary trees (`t_btree`) +- time struct (`t_mytime`) + +## ft_printf + +printf rewrite + +## get_next_line + +read one line from a file descriptor, supports calls between multiple file descriptors. diff --git a/42sh/libft/includes/btree.h b/42sh/libft/includes/btree.h new file mode 100644 index 00000000..dd0b2c97 --- /dev/null +++ b/42sh/libft/includes/btree.h @@ -0,0 +1,55 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* btree.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/16 11:13:15 by jhalford #+# #+# */ +/* Updated: 2017/03/14 17:40:20 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); +t_btree *btree_map(t_btree *root, void *(*f)(void *)); +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/libft/includes/cliopts.h b/42sh/libft/includes/cliopts.h new file mode 100644 index 00000000..b39d445b --- /dev/null +++ b/42sh/libft/includes/cliopts.h @@ -0,0 +1,43 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* cliopts.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/14 20:22:56 by jhalford #+# #+# */ +/* Updated: 2017/03/27 19:46:01 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef CLIOPTS_H +# define CLIOPTS_H + +# include "libft.h" +# include "error.h" + +typedef struct s_cliopts t_cliopts; +typedef struct s_data_template t_data_template; +typedef long long t_flag; + +struct s_cliopts +{ + char c; + char *str; + t_flag flag_on; + t_flag flag_off; + int (*get)(); + int arg_required:1; +}; + +struct s_data_template +{ + t_flag flag; + char **av_data; +}; + +int cliopts_get(char **av, t_cliopts opt_map[], void *data); +t_cliopts *cliopts_getmap_long(t_cliopts opt_map[], char *arg); +t_cliopts *cliopts_getmap_short(t_cliopts opt_map[], char arg); + +#endif diff --git a/42sh/libft/includes/color.h b/42sh/libft/includes/color.h new file mode 100644 index 00000000..698e6c51 --- /dev/null +++ b/42sh/libft/includes/color.h @@ -0,0 +1,56 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* color.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/25 13:36:48 by jhalford #+# #+# */ +/* Updated: 2017/02/18 20:01:33 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 "\e[0m" +# define ON_BOLD "\e[1m" + +# define ON_UNDERLINED "\e[4m" +# define ON_INVERTED "\e[7m" + +# define FG_BLACK "\e[30m" +# define FG_RED "\e[31m" +# define FG_GREEN "\e[32m" +# define FG_YELLOW "\e[33m" +# define FG_BLUE "\e[34m" +# define FG_MAGENTA "\e[35m" +# define FG_CYAN "\e[36m" + +# define BG_BLACK "\e[40m" +# define BG_RED "\e[41m" +# define BG_GREEN "\e[42m" +# define BG_YELLOW "\e[43m" +# define BG_BLUE "\e[44m" +# define BG_MAGENTA "\e[45m" +# define BG_CYAN "\e[46m" +# define BG_DEFAULT "\e[49m" + +# define FBG_DEFAULT FG_DEFAULT BG_DEFAULT + +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/libft/includes/dlst.h b/42sh/libft/includes/dlst.h new file mode 100644 index 00000000..a269909e --- /dev/null +++ b/42sh/libft/includes/dlst.h @@ -0,0 +1,35 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* dlst.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/07 13:21:04 by jhalford #+# #+# */ +/* Updated: 2017/03/07 17:25:50 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/libft/includes/error.h b/42sh/libft/includes/error.h new file mode 100644 index 00000000..5ea206a9 --- /dev/null +++ b/42sh/libft/includes/error.h @@ -0,0 +1,50 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* error.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/14 15:34:21 by jhalford #+# #+# */ +/* Updated: 2017/03/25 01:53:21 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef ERROR_H +# define ERROR_H + +# include "libft.h" +# include + +# define DG_MSG "{inv}{ran}%5i{yel}%21s {bol}{blu}%-3d{eoc}" +# define DG_ARGS getpid(), getpid(), ft_path_notdir(__FILE__), __LINE__ +# define DG(s, ...) ft_dprintf(STDBUG,DG_MSG s "{eoc}\n",DG_ARGS,##__VA_ARGS__) + +# define ERR_PROTO(u, m) "{red}%s: %s{eoc}\n", u, m +# define ERR_MSG(u, m) ft_dprintf(2, ERR_PROTO(u, m)) +# define ERR_SET(n, ...) error_set(n, ##__VA_ARGS__) +# define ERRMSG_MAX_SIZE 150 + +enum e_errors +{ + E_NOERR, + E_CO_INV, + E_CO_INVL, + E_CO_MULT, + E_CO_MISS, + E_CO_MISSL, + E_SYS_NOFILE, + E_SYS_ISDIR, + E_SYS_NOPERM, + E_MAX, +}; + +extern char g_error_msg[E_MAX][ERRMSG_MAX_SIZE]; +extern char *g_errmsg; +extern int g_errnum; +extern char **g_argv; + +int error_set(int n, ...); +int ft_perror(char *utility); + +#endif diff --git a/42sh/libft/includes/ft_printf.h b/42sh/libft/includes/ft_printf.h new file mode 100644 index 00000000..e9299538 --- /dev/null +++ b/42sh/libft/includes/ft_printf.h @@ -0,0 +1,80 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ftprintf.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/07 13:22:54 by jhalford #+# #+# */ +/* Updated: 2017/03/20 09:23:06 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(char **final, char **str, va_list ap); +t_fmt *ft_printf_parse(char **format, va_list ap); + +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/libft/includes/ft_types.h b/42sh/libft/includes/ft_types.h new file mode 100644 index 00000000..a8f001cc --- /dev/null +++ b/42sh/libft/includes/ft_types.h @@ -0,0 +1,22 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_types.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/25 01:56:58 by jhalford #+# #+# */ +/* Updated: 2017/03/25 02:02:06 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef FT_TYPES_H +# define FT_TYPES_H + +typedef struct s_stos t_stos; +typedef struct s_stof t_stof; +typedef struct s_itof t_itof; +typedef long long int t_flag; +typedef long long int t_type; + +#endif diff --git a/42sh/libft/includes/get_next_line.h b/42sh/libft/includes/get_next_line.h new file mode 100644 index 00000000..b63d0ac2 --- /dev/null +++ b/42sh/libft/includes/get_next_line.h @@ -0,0 +1,31 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* get_next_line.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/05 12:21:36 by jhalford #+# #+# */ +/* Updated: 2016/12/15 13:07:58 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef GET_NEXT_LINE_H +# define GET_NEXT_LINE_H +# define BUFF_SIZE 32 + +# include "libft.h" +# include +# include + +typedef struct s_save t_save; + +struct s_save +{ + int fd; + char *str; +}; + +int get_next_line(int const fd, char **line); + +#endif diff --git a/42sh/libft/includes/libft.h b/42sh/libft/includes/libft.h new file mode 100644 index 00000000..96b3f0c3 --- /dev/null +++ b/42sh/libft/includes/libft.h @@ -0,0 +1,90 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* libft.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/07 13:49:04 by jhalford #+# #+# */ +/* Updated: 2017/03/26 21:12:20 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef LIBFT_H +# define LIBFT_H + +# include +# include +# include +# include +# include +# include + +# include "ft_types.h" +# include "error.h" +# include "color.h" +# include "cliopts.h" + +# include "lst.h" +# include "dlst.h" +# include "btree.h" + +# include "str.h" +# include "sstr.h" +# include "math.h" +# include "mytime.h" +# include "get_next_line.h" +# include "sys.h" + +struct s_stos +{ + char *key; + char *val; +}; + +struct s_stof +{ + char *name; + int (*f)(); +}; + +struct s_itof +{ + int id; + int (*f)(); +}; + +int ft_printf(const char *format, ...); +int ft_dprintf(int fd, const char *format, ...); +int ft_vdprintf(int fd, const char *format, va_list ap); +int ft_asprintf(char **ret, const char *format, ...); +int ft_vasprintf(char **ret, const char *format, va_list ap); + +void *ft_malloc(size_t size); +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); +void *ft_memalloc(size_t size); +void ft_memdel(void **ap); + +int ft_putchar(int c); +void ft_putstr(char const *s); +void ft_putendl(char const *s); +void ft_putnbr(long n); +void ft_putnbr_hex(long n); + +int ft_error_message(char *message); + +int ft_putchar_fd(int 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(long n, int fd); +void ft_putnbr_hex_fd(long n, int fd); + +void *ft_realloc(void *data, int size); + +#endif diff --git a/42sh/libft/includes/lst.h b/42sh/libft/includes/lst.h new file mode 100644 index 00000000..2b6a9e24 --- /dev/null +++ b/42sh/libft/includes/lst.h @@ -0,0 +1,84 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* lst.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/07 13:27:46 by jhalford #+# #+# */ +/* Updated: 2017/03/24 20:09:05 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; + +int pop(t_list **lst); +t_list *push(t_list **stack, int elem); +int top(t_list *top); + +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); +int ft_lstiter(t_list *lst, int (*f)()); +t_list *ft_lstmap(t_list *lst, void *(*f)(void *)); + +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/libft/includes/math.h b/42sh/libft/includes/math.h new file mode 100644 index 00000000..2a54ae68 --- /dev/null +++ b/42sh/libft/includes/math.h @@ -0,0 +1,38 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* math.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/20 15:41:59 by jhalford #+# #+# */ +/* Updated: 2017/03/20 15:42:13 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef MATH_H +# define MATH_H + +# define FT_WS(x) (x == ' ' || x == '\t' || x == '\n') +# define FT_ABS(x) (((x) < 0) ? -(x) : (x)) +# define FT_NEG(x) ((x) < 0) +# define FT_POS(x) ((x) > 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)) + +char *ft_itoa(int n); +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); +void *id(void *data); + +#endif diff --git a/42sh/libft/includes/mytime.h b/42sh/libft/includes/mytime.h new file mode 100644 index 00000000..61444457 --- /dev/null +++ b/42sh/libft/includes/mytime.h @@ -0,0 +1,34 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* mytime.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/25 11:43:12 by jhalford #+# #+# */ +/* Updated: 2017/02/18 13:11:26 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef MYTIME_H +# define MYTIME_H +# include "libft.h" + +struct s_mytime +{ + char *year; + char *month; + char *day; + char *hour; + char *min; + char *sec; +}; + +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 diff --git a/42sh/libft/includes/sstr.h b/42sh/libft/includes/sstr.h new file mode 100644 index 00000000..b1f10bc2 --- /dev/null +++ b/42sh/libft/includes/sstr.h @@ -0,0 +1,27 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* sstr.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/18 13:16:25 by jhalford #+# #+# */ +/* Updated: 2017/03/24 17:46:36 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef SSTR_H +# define SSTR_H + +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); +char **ft_sstrmerge(char **s1, char **s2); +void ft_sstrdel(char **sstr, int index); +void ft_sstrfree(char **sstr); +char *ft_sstrcat(char **sstr, char sep); +char *ft_sstrstr(char **sstr, char *find); + +#endif diff --git a/42sh/libft/includes/str.h b/42sh/libft/includes/str.h new file mode 100644 index 00000000..44325726 --- /dev/null +++ b/42sh/libft/includes/str.h @@ -0,0 +1,75 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* str.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/18 13:05:53 by jhalford #+# #+# */ +/* Updated: 2017/03/07 11:36:58 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef STR_H +# define STR_H + +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); + +size_t ft_strlen(const char *s); +size_t ft_strlenchr(const char *s, char c); +char *ft_strdup(const char *s1); +char *ft_strdupchr(const char *str, char c); +char *ft_strduptr(char *str, int (*is)(int c)); +char *ft_strcpy(char *dst, const char *src); +char *ft_strncpy(char *dst, const char *src, size_t len); +char *ft_strchrcpy(char *dst, const char *str, char c); +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); + +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_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_strtok(char *s, const char *delim); +size_t ft_strcspn(char *s, const char *delim); + +char *ft_path_notdir(char *path); +int ft_stris(char *str, int (*f)()); + +#endif diff --git a/42sh/libft/includes/sys.h b/42sh/libft/includes/sys.h new file mode 100644 index 00000000..25f77020 --- /dev/null +++ b/42sh/libft/includes/sys.h @@ -0,0 +1,44 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* sys.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/14 17:24:23 by jhalford #+# #+# */ +/* Updated: 2017/03/27 00:05:25 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef SYS_H +# define SYS_H + +# define FT_XATTR_SIZE 10000 +# define STDIN STDIN_FILENO +# define STDOUT STDOUT_FILENO +# define STDERR STDERR_FILENO +# define STDBUG 3 + +# define PIPE_READ 0 +# define PIPE_WRITE 1 + +# include +# include +# include +# include +# include + +int ft_xattr_print(char *path); +int ft_xattr_count(char *path); + +char *ft_getenv(char **env, char *key); + +int try_access(char *file, int exists, t_flag a_flag); +int is_directory(const char *path); +char *create_directory(const char *path, const char *old_pathnames); + +int dup2_close(int fd1, int fd2); +int fd_replace(int fd1, int fd2); +int fd_minor(int fd, int minor); + +#endif diff --git a/42sh/libft/pdf/ft_printf.pdf b/42sh/libft/pdf/ft_printf.pdf new file mode 100644 index 00000000..b4fd9669 Binary files /dev/null and b/42sh/libft/pdf/ft_printf.pdf differ diff --git a/42sh/libft/pdf/get_next_line.fr.pdf b/42sh/libft/pdf/get_next_line.fr.pdf new file mode 100644 index 00000000..03d33367 Binary files /dev/null and b/42sh/libft/pdf/get_next_line.fr.pdf differ diff --git a/42sh/libft/pdf/libft.fr.pdf b/42sh/libft/pdf/libft.fr.pdf new file mode 100644 index 00000000..b3951a0a Binary files /dev/null and b/42sh/libft/pdf/libft.fr.pdf differ diff --git a/42sh/libft/src/btree/btree_apply_by_level.c b/42sh/libft/src/btree/btree_apply_by_level.c new file mode 100644 index 00000000..14e537f7 --- /dev/null +++ b/42sh/libft/src/btree/btree_apply_by_level.c @@ -0,0 +1,46 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* btree_apply_by_level.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/08/19 12:06:15 by jhalford #+# #+# */ +/* Updated: 2017/03/14 17:25:46 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "btree.h" + +int g_level = 0; + +static void btree_apply_to_level( + t_btree *root, + int level, + int is_first_elem, + void (*applyf)(void *item, int current_level, int is_first_elem)) +{ + if (level == g_level) + { + (*applyf)(root->item, level, is_first_elem); + return ; + } + if (root->left) + btree_apply_to_level(root->left, level + 1, is_first_elem, applyf); + if (root->right) + btree_apply_to_level(root->right, level + 1, 0, applyf); +} + +void btree_apply_by_level( + t_btree *root, + void (*applyf)(void *item, int current_level, int is_first_elem)) +{ + int height; + + height = btree_level_count(root); + while (g_level < height) + { + btree_apply_to_level(root, 0, 1, applyf); + g_level++; + } +} diff --git a/42sh/libft/src/btree/btree_apply_infix.c b/42sh/libft/src/btree/btree_apply_infix.c new file mode 100644 index 00000000..93a18b7d --- /dev/null +++ b/42sh/libft/src/btree/btree_apply_infix.c @@ -0,0 +1,23 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* btree_create_node.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/08/16 13:43:51 by jhalford #+# #+# */ +/* Updated: 2017/03/06 18:22:31 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "btree.h" + +void btree_apply_infix(t_btree *root, void (*applyf)(void *)) +{ + if (root->left) + btree_apply_infix(root->left, applyf); + (*applyf)(root->item); + if (root->right) + btree_apply_infix(root->right, applyf); + return ; +} diff --git a/42sh/libft/src/btree/btree_apply_prefix.c b/42sh/libft/src/btree/btree_apply_prefix.c new file mode 100644 index 00000000..e7e4332c --- /dev/null +++ b/42sh/libft/src/btree/btree_apply_prefix.c @@ -0,0 +1,22 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* btree_create_node.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/08/16 13:43:51 by jhalford #+# #+# */ +/* Updated: 2016/08/18 21:06:44 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "btree.h" + +void btree_apply_prefix(t_btree *root, void (*applyf)(void *)) +{ + (*applyf)(root->item); + if (root->left) + btree_apply_prefix(root->left, applyf); + if (root->right) + btree_apply_prefix(root->right, applyf); +} diff --git a/42sh/libft/src/btree/btree_apply_suffix.c b/42sh/libft/src/btree/btree_apply_suffix.c new file mode 100644 index 00000000..ae103242 --- /dev/null +++ b/42sh/libft/src/btree/btree_apply_suffix.c @@ -0,0 +1,23 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* btree_apply_suffix.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/05 11:43:08 by jhalford #+# #+# */ +/* Updated: 2016/12/05 11:43:13 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "btree.h" + +void btree_apply_suffix(t_btree *root, void (*applyf)(void *)) +{ + if (root->left) + btree_apply_suffix(root->left, applyf); + if (root->right) + btree_apply_suffix(root->right, applyf); + (*applyf)(root->item); + return ; +} diff --git a/42sh/libft/src/btree/btree_create_node.c b/42sh/libft/src/btree/btree_create_node.c new file mode 100644 index 00000000..cc365537 --- /dev/null +++ b/42sh/libft/src/btree/btree_create_node.c @@ -0,0 +1,35 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* btree_create_node.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/08/16 13:43:51 by jhalford #+# #+# */ +/* Updated: 2017/03/21 15:43:50 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "btree.h" + +t_btree *btree_create_node(void const *item, size_t content_size) +{ + t_btree *new; + + if (!(new = (t_btree *)ft_malloc(sizeof(t_btree)))) + return (NULL); + new->left = 0; + new->right = 0; + if (!item) + { + new->content_size = 0; + new->item = NULL; + } + else + { + new->content_size = content_size; + new->item = ft_memalloc(content_size + 1); + ft_memcpy(new->item, item, content_size); + } + return (new); +} diff --git a/42sh/libft/src/btree/btree_del.c b/42sh/libft/src/btree/btree_del.c new file mode 100644 index 00000000..8b72f78a --- /dev/null +++ b/42sh/libft/src/btree/btree_del.c @@ -0,0 +1,23 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* btree_del.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/05 11:43:03 by jhalford #+# #+# */ +/* Updated: 2017/03/21 19:43:51 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "btree.h" + +void btree_del(t_btree **root, void (*del)(void *, size_t)) +{ + if (root && *root && del) + { + btree_del(&(*root)->left, del); + btree_del(&(*root)->right, del); + btree_delone(root, del); + } +} diff --git a/42sh/libft/src/btree/btree_delone.c b/42sh/libft/src/btree/btree_delone.c new file mode 100644 index 00000000..17ce1c4a --- /dev/null +++ b/42sh/libft/src/btree/btree_delone.c @@ -0,0 +1,24 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* btree_delone.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/05 11:45:51 by jhalford #+# #+# */ +/* Updated: 2016/12/15 12:48:55 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "btree.h" + +void btree_delone(t_btree **root, void (*del)(void *, size_t)) +{ + if (root && *root) + { + if (del) + (*del)((*root)->item, (*root)->content_size); + free(*root); + *root = NULL; + } +} diff --git a/42sh/libft/src/btree/btree_insert_data.c b/42sh/libft/src/btree/btree_insert_data.c new file mode 100644 index 00000000..a6e262fc --- /dev/null +++ b/42sh/libft/src/btree/btree_insert_data.c @@ -0,0 +1,43 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* btree_create_node.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/08/16 13:43:51 by jhalford #+# #+# */ +/* Updated: 2016/11/14 16:12:47 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "btree.h" + +void btree_insert_data( + t_btree **root, + void *item, + size_t content_size, + int (*cmpf)(void *, void *)) +{ + t_btree *node; + + if (!*root) + { + *root = btree_create_node(item, content_size); + return ; + } + node = *root; + if ((*cmpf)(item, node->item) < 0) + { + if (node->left) + btree_insert_data(&node->left, item, content_size, cmpf); + else + node->left = btree_create_node(item, content_size); + } + else + { + if (node->right) + btree_insert_data(&node->right, item, content_size, cmpf); + else + node->right = btree_create_node(item, content_size); + } +} diff --git a/42sh/libft/src/btree/btree_level_count.c b/42sh/libft/src/btree/btree_level_count.c new file mode 100644 index 00000000..41248654 --- /dev/null +++ b/42sh/libft/src/btree/btree_level_count.c @@ -0,0 +1,21 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* btree_create_node.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/08/16 13:43:51 by jhalford #+# #+# */ +/* Updated: 2016/08/25 17:46:00 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "btree.h" + +int btree_level_count(t_btree *root) +{ + return (root + ? 1 + FT_MAX(btree_level_count(root->left), + btree_level_count(root->right)) + : 0); +} diff --git a/42sh/libft/src/btree/btree_map.c b/42sh/libft/src/btree/btree_map.c new file mode 100644 index 00000000..47b92852 --- /dev/null +++ b/42sh/libft/src/btree/btree_map.c @@ -0,0 +1,27 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* btree_map.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/08 11:50:46 by jhalford #+# #+# */ +/* Updated: 2017/03/24 15:49:42 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "btree.h" + +t_btree *btree_map(t_btree *root, void *(*f)(void *)) +{ + t_btree *new; + + if (!root) + return (NULL); + if (!(new = (t_btree *)ft_malloc(sizeof(*new)))) + return (NULL); + new->item = (*f)(root->item); + new->left = btree_map(root->left, f); + new->right = btree_map(root->right, f); + return (new); +} diff --git a/42sh/libft/src/btree/btree_print.c b/42sh/libft/src/btree/btree_print.c new file mode 100644 index 00000000..bc1961dc --- /dev/null +++ b/42sh/libft/src/btree/btree_print.c @@ -0,0 +1,82 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* btree_print.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/14 18:06:24 by jhalford #+# #+# */ +/* Updated: 2017/03/20 21:06:28 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "btree.h" + +static int print_t2(t_printdata data, char s[20][255], char b[20]) +{ + int width; + int i; + + width = 5; + i = -1; + while (++i < width) + s[2 * data.depth][data.offset + data.left + i] = b[i]; + i = -1; + if (data.depth && data.is_left) + { + while (++i < width + data.right) + s[2 * data.depth - 1] + [data.offset + data.left + width / 2 + i] = '-'; + s[2 * data.depth - 1][data.offset + data.left + width / 2] = '+'; + s[2 * data.depth - 1] + [data.offset + data.left + data.right + 3 * width / 2] = '+'; + } + else if (data.depth && !data.is_left) + { + while (++i < width + data.left) + s[2 * data.depth - 1][data.offset - width / 2 + i] = '-'; + s[2 * data.depth - 1][data.offset + data.left + width / 2] = '+'; + s[2 * data.depth - 1][data.offset - width / 2 - 1] = '+'; + } + return (data.left + width + data.right); +} + +static int print_t(t_btree *tree, + t_printdata data, char s[20][255], char *(*printer)(void *)) +{ + char b[20]; + int width; + + width = 5; + if (!tree) + return (0); + sprintf(b, "%5s", printer(tree->item)); + data.left = print_t(tree->left, (t_printdata){ + 1, data.offset, data.depth + 1, data.left, data.right}, s, printer); + data.right = print_t(tree->right, (t_printdata){ + 0, data.offset + data.left + width, data.depth + 1, + data.left, data.right}, s, printer); + return (print_t2(data, s, b)); +} + +void btree_print(int fd, t_btree *tree, char *(*printer)(void *)) +{ + char s[20][255]; + char empty[255]; + int i; + + i = -1; + while (++i < 20) + sprintf(s[i], "%80s", " "); + sprintf(empty, "%80s", " "); + print_t(tree, (t_printdata){0, 0, 0, 0, 0}, s, printer); + i = -1; + while (++i < 20) + { + if (ft_strcmp(s[i], empty) == 0) + break ; + if (i == 0 && ft_strcmp(s[1], empty) == 0) + break ; + ft_dprintf(fd, "%s\n", s[i]); + } +} diff --git a/42sh/libft/src/btree/btree_search_item.c b/42sh/libft/src/btree/btree_search_item.c new file mode 100644 index 00000000..a7a1eb68 --- /dev/null +++ b/42sh/libft/src/btree/btree_search_item.c @@ -0,0 +1,30 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* btree_create_node.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/08/16 13:43:51 by jhalford #+# #+# */ +/* Updated: 2016/08/23 19:04:56 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "btree.h" + +void *btree_search_item(t_btree *root, + void *data_ref, int (*cmpf)(void *, void *)) +{ + void *out; + + out = NULL; + if (root) + { + out = btree_search_item(root->left, data_ref, cmpf); + if (!out && ((*cmpf)(root->item, data_ref) == 0)) + out = root->item; + if (!out) + out = btree_search_item(root->right, data_ref, cmpf); + } + return (out); +} diff --git a/42sh/libft/src/char/ft_isalnum.c b/42sh/libft/src/char/ft_isalnum.c new file mode 100644 index 00000000..673b6e89 --- /dev/null +++ b/42sh/libft/src/char/ft_isalnum.c @@ -0,0 +1,22 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_isalnum.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/03 14:56:18 by jhalford #+# #+# */ +/* Updated: 2016/11/03 15:31:33 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +int ft_isalnum(int c) +{ + if ((c >= 'a' && c <= 'z') + || (c >= 'A' && c <= 'Z') + || (c >= '0' && c <= '9')) + return (c); + return (0); +} diff --git a/42sh/libft/src/char/ft_isalpha.c b/42sh/libft/src/char/ft_isalpha.c new file mode 100644 index 00000000..ac5d276e --- /dev/null +++ b/42sh/libft/src/char/ft_isalpha.c @@ -0,0 +1,20 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_isalpha.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/03 14:56:24 by jhalford #+# #+# */ +/* Updated: 2017/03/07 11:59:16 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +int ft_isalpha(int c) +{ + if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) + return (c); + return (0); +} diff --git a/42sh/libft/src/char/ft_isascii.c b/42sh/libft/src/char/ft_isascii.c new file mode 100644 index 00000000..52a85067 --- /dev/null +++ b/42sh/libft/src/char/ft_isascii.c @@ -0,0 +1,20 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_isascii.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/03 14:56:28 by jhalford #+# #+# */ +/* Updated: 2016/11/03 15:35:42 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +int ft_isascii(int c) +{ + if (c >= 0 && c <= 127) + return (1); + return (0); +} diff --git a/42sh/libft/src/char/ft_isdigit.c b/42sh/libft/src/char/ft_isdigit.c new file mode 100644 index 00000000..510371c2 --- /dev/null +++ b/42sh/libft/src/char/ft_isdigit.c @@ -0,0 +1,23 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_isdigit.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/03 14:56:33 by jhalford #+# #+# */ +/* Updated: 2016/11/03 14:56:34 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +int ft_isdigit(int c) +{ + unsigned char a; + + a = (unsigned char)c; + if (a >= '0' && a <= '9') + return (a); + return (0); +} diff --git a/42sh/libft/src/char/ft_isprint.c b/42sh/libft/src/char/ft_isprint.c new file mode 100644 index 00000000..74a46640 --- /dev/null +++ b/42sh/libft/src/char/ft_isprint.c @@ -0,0 +1,20 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_isprint.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/03 14:56:38 by jhalford #+# #+# */ +/* Updated: 2016/11/03 15:32:40 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +int ft_isprint(int c) +{ + if (c >= 32 && c <= 126) + return (c); + return (0); +} diff --git a/42sh/libft/src/char/ft_tolower.c b/42sh/libft/src/char/ft_tolower.c new file mode 100644 index 00000000..3992c4c9 --- /dev/null +++ b/42sh/libft/src/char/ft_tolower.c @@ -0,0 +1,20 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_tolower.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/03 14:58:46 by jhalford #+# #+# */ +/* Updated: 2016/11/03 15:24:09 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +int ft_tolower(int c) +{ + if (c >= 'A' && c <= 'Z') + return (c + 32); + return (c); +} diff --git a/42sh/libft/src/char/ft_toupper.c b/42sh/libft/src/char/ft_toupper.c new file mode 100644 index 00000000..3aa9ea10 --- /dev/null +++ b/42sh/libft/src/char/ft_toupper.c @@ -0,0 +1,20 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_toupper.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/03 14:53:58 by jhalford #+# #+# */ +/* Updated: 2016/11/03 15:24:40 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +int ft_toupper(int c) +{ + if (c >= 'a' && c <= 'z') + return (c - 32); + return (c); +} diff --git a/42sh/libft/src/cliopts/cliopts_get.c b/42sh/libft/src/cliopts/cliopts_get.c new file mode 100644 index 00000000..05e8a3f8 --- /dev/null +++ b/42sh/libft/src/cliopts/cliopts_get.c @@ -0,0 +1,110 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* cliopts_get.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/14 20:04:04 by jhalford #+# #+# */ +/* Updated: 2017/03/25 15:00:35 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +/* +** void *data must be a structure starting with `int flag` +** to do polymorphism with t_data_template ! +*/ + +#include "cliopts.h" + +static char *check_required(char ***av, char *arg) +{ + char *ret; + + if (!av || !*av) + return (NULL); + if (!arg || !*arg || !*(arg + 1)) + return (*++(*av)); + ret = arg + 1; + return (ret); +} + +static int cliopts_parse_short( + char ***av, t_cliopts opt_map[], void *data) +{ + t_cliopts *map; + char *arg; + int i; + char *tmp; + + arg = **av + 1; + i = -1; + while (arg[++i] && !(tmp = NULL)) + { + if (!(map = cliopts_getmap_short(opt_map, arg[i]))) + return (ERR_SET(E_CO_INV, arg[i])); + ((t_data_template*)data)->flag |= map->flag_on; + ((t_data_template*)data)->flag &= ~map->flag_off; + if (map->get) + { + if (map->arg_required && !(tmp = check_required(av, arg + i))) + return (ERR_SET(E_CO_MISS, *arg)); + tmp = tmp ? tmp : **av; + if ((map->get)(tmp, data)) + return (ERR_SET(E_CO_MISS, *arg)); + if (map->arg_required) + break ; + } + } + return (++(*av) ? 0 : 0); +} + +static int cliopts_parse_long( + char ***av, t_cliopts opt_map[], void *data) +{ + t_cliopts *map; + char *arg; + char *tmp; + + arg = **av + 2; + tmp = NULL; + if (!(map = cliopts_getmap_long(opt_map, arg))) + return (ERR_SET(E_CO_INVL, arg)); + ((t_data_template*)data)->flag |= map->flag_on; + ((t_data_template*)data)->flag &= ~map->flag_off; + if (map->get) + { + if (map->arg_required && !(tmp = check_required(av, NULL))) + return (ERR_SET(E_CO_MISS, *arg)); + if ((map->get)(tmp, data)) + return (ERR_SET(E_CO_MISSL, arg)); + } + ++(*av); + return (0); +} + +int cliopts_get(char **av, t_cliopts opt_map[], void *data) +{ + if (!av) + return (1); + av++; + while (av && *av) + { + if (ft_strcmp(*av, "-") == 0 || (ft_strcmp(*av, "--") == 0 && av++)) + break ; + else if ((*av)[0] == '-' && (*av)[1] == '-') + { + if (cliopts_parse_long(&av, opt_map, data)) + return (1); + } + else if ((*av)[0] == '-') + { + if (cliopts_parse_short(&av, opt_map, data)) + return (1); + } + else + break ; + } + ((t_data_template*)data)->av_data = av; + return (0); +} diff --git a/42sh/libft/src/cliopts/cliopts_getmap.c b/42sh/libft/src/cliopts/cliopts_getmap.c new file mode 100644 index 00000000..189e22ba --- /dev/null +++ b/42sh/libft/src/cliopts/cliopts_getmap.c @@ -0,0 +1,35 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* cliopts_getmap.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/25 14:59:03 by jhalford #+# #+# */ +/* Updated: 2017/03/25 15:01:10 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "cliopts.h" + +t_cliopts *cliopts_getmap_long(t_cliopts opt_map[], char *arg) +{ + int i; + + i = -1; + while (opt_map[++i].c) + if (!ft_strcmp(opt_map[i].str, arg)) + return (&opt_map[i]); + return (NULL); +} + +t_cliopts *cliopts_getmap_short(t_cliopts opt_map[], char arg) +{ + int i; + + i = -1; + while (opt_map[++i].c) + if (opt_map[i].c == arg) + return (&opt_map[i]); + return (NULL); +} diff --git a/42sh/libft/src/color/ft_color_mk.c b/42sh/libft/src/color/ft_color_mk.c new file mode 100644 index 00000000..db75d7cc --- /dev/null +++ b/42sh/libft/src/color/ft_color_mk.c @@ -0,0 +1,19 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_color_mk.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/27 11:35:18 by jhalford #+# #+# */ +/* Updated: 2016/12/12 11:54:49 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void ft_color_mk(t_color *color, char fg[7], char bg[7]) +{ + ft_strcpy(color->fg, fg); + ft_strcpy(color->bg, bg); +} diff --git a/42sh/libft/src/color/ft_color_mkif.c b/42sh/libft/src/color/ft_color_mkif.c new file mode 100644 index 00000000..707a5c8c --- /dev/null +++ b/42sh/libft/src/color/ft_color_mkif.c @@ -0,0 +1,19 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_color_mk.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/27 11:35:18 by jhalford #+# #+# */ +/* Updated: 2016/12/03 12:17:14 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void ft_color_mkif(t_color *color, int cond, char fg[7], char bg[7]) +{ + if (cond) + ft_color_mk(color, fg, bg); +} diff --git a/42sh/libft/src/color/ft_color_reset.c b/42sh/libft/src/color/ft_color_reset.c new file mode 100644 index 00000000..4b557bff --- /dev/null +++ b/42sh/libft/src/color/ft_color_reset.c @@ -0,0 +1,19 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_color_reset.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/25 13:48:05 by jhalford #+# #+# */ +/* Updated: 2016/11/25 14:06:26 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void ft_color_reset(void) +{ + ft_putstr(FG_DEFAULT); + ft_putstr(BG_DEFAULT); +} diff --git a/42sh/libft/src/color/ft_color_set.c b/42sh/libft/src/color/ft_color_set.c new file mode 100644 index 00000000..99d9c0d0 --- /dev/null +++ b/42sh/libft/src/color/ft_color_set.c @@ -0,0 +1,22 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_color_set.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/25 13:53:46 by jhalford #+# #+# */ +/* Updated: 2016/12/12 11:55:03 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void ft_color_set(t_color color) +{ + char out[20]; + + ft_strcpy(out, color.fg); + ft_strcat(out, color.bg); + ft_putstr(out); +} diff --git a/42sh/libft/src/dlst/ft_dlstadd_after.c b/42sh/libft/src/dlst/ft_dlstadd_after.c new file mode 100644 index 00000000..19dc852a --- /dev/null +++ b/42sh/libft/src/dlst/ft_dlstadd_after.c @@ -0,0 +1,30 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_dlst_add_after.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/07 13:27:04 by jhalford #+# #+# */ +/* Updated: 2016/11/07 13:27:36 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void ft_dlstadd_after(t_dlist **alst, t_dlist *new) +{ + if (new) + { + new->prev = (*alst); + if (*alst) + new->next = (*alst)->next; + else + new->next = NULL; + if (new->next) + new->next->prev = new; + if (new->prev) + new->prev->next = new; + *alst = new; + } +} diff --git a/42sh/libft/src/dlst/ft_dlstadd_before.c b/42sh/libft/src/dlst/ft_dlstadd_before.c new file mode 100644 index 00000000..e2d6b2e8 --- /dev/null +++ b/42sh/libft/src/dlst/ft_dlstadd_before.c @@ -0,0 +1,28 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_dlst_add_before.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/07 13:27:09 by jhalford #+# #+# */ +/* Updated: 2016/11/07 13:27:10 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void ft_dlstadd_before(t_dlist **alst, t_dlist *new) +{ + if (new) + { + new->next = (*alst); + if (*alst) + new->prev = (*alst)->prev; + if (new->next) + new->next->prev = new; + if (new->prev) + new->prev->next = new; + *alst = new; + } +} diff --git a/42sh/libft/src/dlst/ft_dlstdel.c b/42sh/libft/src/dlst/ft_dlstdel.c new file mode 100644 index 00000000..94b43f6b --- /dev/null +++ b/42sh/libft/src/dlst/ft_dlstdel.c @@ -0,0 +1,41 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_dlstdel.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/14 17:55:40 by jhalford #+# #+# */ +/* Updated: 2016/12/07 17:29:54 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +static void ft_dlstdelback(t_dlist **alst, void (*del)(void *, size_t)) +{ + if (alst && *alst && del) + { + ft_dlstdelback(&(*alst)->prev, del); + ft_dlstdelone(alst, del); + } +} + +static void ft_dlstdelfront(t_dlist **alst, void (*del)(void *, size_t)) +{ + if (alst && *alst && del) + { + ft_dlstdelfront(&(*alst)->next, del); + ft_dlstdelone(alst, del); + } +} + +void ft_dlstdel(t_dlist **alst, void (*del)(void *, size_t)) +{ + if (alst && *alst && del) + { + ft_dlstdelback(&(*alst)->prev, del); + ft_dlstdelfront(&(*alst)->next, del); + ft_dlstdelone(alst, del); + } +} diff --git a/42sh/libft/src/dlst/ft_dlstdelone.c b/42sh/libft/src/dlst/ft_dlstdelone.c new file mode 100644 index 00000000..55826853 --- /dev/null +++ b/42sh/libft/src/dlst/ft_dlstdelone.c @@ -0,0 +1,34 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_dlst_delone.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/07 13:27:13 by jhalford #+# #+# */ +/* Updated: 2016/11/14 17:52:58 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void ft_dlstdelone(t_dlist **alst, void (*del)(void *, size_t)) +{ + t_dlist *tmp; + + tmp = *alst; + if (tmp) + { + if (del) + (*del)(tmp->content, tmp->content_size); + if (tmp->next) + tmp->next->prev = tmp->prev; + if (tmp->prev) + tmp->prev->next = tmp->next; + if (tmp->prev) + *alst = tmp->prev; + else + *alst = tmp->next; + free(tmp); + } +} diff --git a/42sh/libft/src/dlst/ft_dlstlast.c b/42sh/libft/src/dlst/ft_dlstlast.c new file mode 100644 index 00000000..1286c32c --- /dev/null +++ b/42sh/libft/src/dlst/ft_dlstlast.c @@ -0,0 +1,20 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_dlst_last.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/07 13:27:15 by jhalford #+# #+# */ +/* Updated: 2016/11/07 13:27:15 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +t_dlist *ft_dlstlast(t_dlist *list) +{ + while (list && list->next) + list = list->next; + return (list); +} diff --git a/42sh/libft/src/dlst/ft_dlstnew.c b/42sh/libft/src/dlst/ft_dlstnew.c new file mode 100644 index 00000000..411bffca --- /dev/null +++ b/42sh/libft/src/dlst/ft_dlstnew.c @@ -0,0 +1,39 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_dlst_new.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/07 13:27:20 by jhalford #+# #+# */ +/* Updated: 2017/03/21 15:43:50 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +t_dlist *ft_dlstnew(void const *content, size_t content_size) +{ + t_dlist *new; + + if (!content) + { + new = ft_malloc(sizeof(*new)); + if (!new) + return (NULL); + new->content_size = 0; + new->content = NULL; + } + else + { + new = (t_dlist *)ft_malloc(sizeof(*new)); + if (!new) + return (NULL); + new->content_size = content_size; + new->content = ft_memalloc(content_size + 1); + ft_memcpy(new->content, content, content_size); + } + new->next = NULL; + new->prev = NULL; + return (new); +} diff --git a/42sh/libft/src/dlst/ft_dlstrtostr.c b/42sh/libft/src/dlst/ft_dlstrtostr.c new file mode 100644 index 00000000..e92e4d8a --- /dev/null +++ b/42sh/libft/src/dlst/ft_dlstrtostr.c @@ -0,0 +1,30 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_dlstrtostr.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/07 13:27:29 by jhalford #+# #+# */ +/* Updated: 2016/11/14 16:13:24 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +char *ft_dlsttostr(t_dlist *list) +{ + char *str; + + if (!list) + return (NULL); + while (list->prev) + list = list->prev; + str = (char *)ft_strnew(sizeof(char) * (ft_dlstsize(list) + 2)); + while (list) + { + ft_strcat(str, (char *)list->content); + list = list->next; + } + return (str); +} diff --git a/42sh/libft/src/dlst/ft_dlstsize.c b/42sh/libft/src/dlst/ft_dlstsize.c new file mode 100644 index 00000000..b536efa2 --- /dev/null +++ b/42sh/libft/src/dlst/ft_dlstsize.c @@ -0,0 +1,36 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_dlst_size.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/07 13:27:23 by jhalford #+# #+# */ +/* Updated: 2016/11/07 13:27:23 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +int ft_dlstsize(t_dlist *list) +{ + int size; + t_dlist *tmp; + + size = 0; + if (list) + size++; + tmp = list; + while (tmp->next) + { + size++; + tmp = tmp->next; + } + tmp = list; + while (tmp->prev) + { + size++; + tmp = tmp->prev; + } + return (size); +} diff --git a/42sh/libft/src/error/error.c b/42sh/libft/src/error/error.c new file mode 100644 index 00000000..6900c094 --- /dev/null +++ b/42sh/libft/src/error/error.c @@ -0,0 +1,48 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* error.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/14 16:47:00 by jhalford #+# #+# */ +/* Updated: 2017/03/25 01:53:25 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "error.h" + +char g_error_msglist[E_MAX][ERRMSG_MAX_SIZE] = +{ + "unknown error 0", + "invalid option -%c", + "invalid option --%s", + "option '%c' awaits argument(s): please don't combine", + "option '%c': missing argument", + "option '%s': missing argument", + "%s: no such file or directory", + "%s: Is a directory", + "%s: Permission denied", +}; + +int g_errnum = 0; +char *g_errmsg = NULL; +char **g_argv; + +int error_set(int n, ...) +{ + va_list ap; + + g_errnum = n; + va_start(ap, n); + ft_strdel(&g_errmsg); + ft_vasprintf(&g_errmsg, g_error_msglist[n], ap); + return (g_errnum); +} + +int ft_perror(char *utility) +{ + utility = utility ? utility : g_argv[0]; + ERR_MSG(utility, g_errmsg); + return (g_errnum); +} diff --git a/42sh/libft/src/ft_printf/ft_conversion.c b/42sh/libft/src/ft_printf/ft_conversion.c new file mode 100644 index 00000000..99f0cc08 --- /dev/null +++ b/42sh/libft/src/ft_printf/ft_conversion.c @@ -0,0 +1,69 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_conversion.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/07 13:31:48 by jhalford #+# #+# */ +/* Updated: 2017/03/21 15:42:19 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ft_printf.h" + +char *ft_signed_conversion(t_fmt *fmt, va_list ap) +{ + static char base10[] = "0123456789"; + long long arg; + + arg = va_arg(ap, int); + (void)fmt; + return (ft_lltoa_base(arg, base10, fmt->flags)); +} + +char *ft_unsigned_conversion(t_fmt *fmt, va_list ap) +{ + unsigned int uiarg; + unsigned long long ullarg; + int i; + + i = 0; + while (fmt->conversion != g_convs[i].id) + i++; + if (!*fmt->modifier + || ft_strequ(fmt->modifier, "hh") + || ft_strequ(fmt->modifier, "h") + || ft_strequ(fmt->modifier, "z")) + { + uiarg = va_arg(ap, int); + return (ft_uitoa_base(uiarg, g_convs[i].base)); + } + ullarg = va_arg(ap, long long); + return (ft_ulltoa_base(ullarg, g_convs[i].base)); +} + +char *ft_char_conversion(t_fmt *fmt, va_list ap) +{ + char *ret; + + (void)fmt; + ret = (char *)ft_malloc(sizeof(char) + 1); + ret[0] = (char)va_arg(ap, int); + ret[1] = '\0'; + return (ret); +} + +char *ft_str_conversion(t_fmt *fmt, va_list ap) +{ + char *ret; + + (void)fmt; + ret = va_arg(ap, char *); + if (ret == NULL) + return (ft_strdup("NULL")); + ret = ft_strdup(ret); + if (fmt->precision && fmt->precision < (int)ft_strlen(ret)) + ret[fmt->precision] = '\0'; + return (ret); +} diff --git a/42sh/libft/src/ft_printf/ft_fmt_simplify.c b/42sh/libft/src/ft_printf/ft_fmt_simplify.c new file mode 100644 index 00000000..f35d2ffa --- /dev/null +++ b/42sh/libft/src/ft_printf/ft_fmt_simplify.c @@ -0,0 +1,31 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* lib_fmt_validate.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/07 13:33:43 by jhalford #+# #+# */ +/* Updated: 2016/11/07 16:53:54 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ft_printf.h" + +void ft_fmt_simplify(t_fmt *fmt) +{ + char hashtag; + + hashtag = '#'; + if (fmt->conversion == 'p') + { + fmt->conversion = 'x'; + if (!ft_strchr(fmt->flags, '#')) + ft_strncat(fmt->flags, &hashtag, 1); + } + if (ft_strchr("DOUCS", fmt->conversion)) + { + fmt->conversion += 32; + ft_strcpy(fmt->modifier, "l"); + } +} diff --git a/42sh/libft/src/ft_printf/ft_fmt_validate_conv.c b/42sh/libft/src/ft_printf/ft_fmt_validate_conv.c new file mode 100644 index 00000000..a10b619c --- /dev/null +++ b/42sh/libft/src/ft_printf/ft_fmt_validate_conv.c @@ -0,0 +1,24 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_fmt_validate_conv.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/07 16:55:36 by jhalford #+# #+# */ +/* Updated: 2016/11/07 16:55:37 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ft_printf.h" + +int ft_fmt_validate_conv(t_fmt *fmt) +{ + if (!ft_strchr(ALL_CONVERSIONS, fmt->conversion)) + { + if (fmt->conversion != '%') + ft_fmt_error_conv(fmt->conversion); + return (1); + } + return (0); +} diff --git a/42sh/libft/src/ft_printf/ft_fmt_validate_flags.c b/42sh/libft/src/ft_printf/ft_fmt_validate_flags.c new file mode 100644 index 00000000..709e3c19 --- /dev/null +++ b/42sh/libft/src/ft_printf/ft_fmt_validate_flags.c @@ -0,0 +1,60 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_fmt_validate_flags.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/07 16:53:07 by jhalford #+# #+# */ +/* Updated: 2017/03/05 15:19:35 by wescande ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ft_printf.h" + +static void ft_fmt_validate_flag_flag(t_fmt *fmt) +{ + char *flag_ptr; + + if (ft_strchr(fmt->flags, '+') && (flag_ptr = ft_strchr(fmt->flags, ' '))) + { + ft_fmt_error_flag_flag(' ', '+'); + *flag_ptr = '.'; + } + if (ft_strchr(fmt->flags, '-') && (flag_ptr = ft_strchr(fmt->flags, '0'))) + { + ft_fmt_error_flag_flag('0', '-'); + *flag_ptr = '.'; + } + if (fmt->precision && (flag_ptr = ft_strchr(fmt->flags, '0'))) + *flag_ptr = '.'; +} + +static void ft_fmt_validate_flag_conv(t_fmt *fmt) +{ + char *flag_ptr; + char flag; + int i; + + i = 0; + flag_ptr = fmt->flags; + while (fmt->conversion != g_convs[i].id) + i++; + while (*flag_ptr) + { + flag = *flag_ptr; + if (!ft_strchr(g_convs[i].allowed_flags, flag)) + { + ft_fmt_error_flag_conv(flag, fmt->conversion); + if (flag == '#') + *flag_ptr = '.'; + } + flag_ptr++; + } +} + +void ft_fmt_validate_flags(t_fmt *fmt) +{ + ft_fmt_validate_flag_conv(fmt); + ft_fmt_validate_flag_flag(fmt); +} diff --git a/42sh/libft/src/ft_printf/ft_fmt_validate_mod.c b/42sh/libft/src/ft_printf/ft_fmt_validate_mod.c new file mode 100644 index 00000000..e5cdb60e --- /dev/null +++ b/42sh/libft/src/ft_printf/ft_fmt_validate_mod.c @@ -0,0 +1,20 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_fmt_validate_conv.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/07 16:53:42 by jhalford #+# #+# */ +/* Updated: 2016/11/07 16:53:52 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ft_printf.h" + +void ft_fmt_validate_mod(t_fmt *fmt) +{ + if (fmt->conversion == 's' || fmt->conversion == 'c') + if (fmt->modifier[0] && ft_strcmp(fmt->modifier, "l")) + ft_fmt_error_mod_conv(fmt->modifier, fmt->conversion); +} diff --git a/42sh/libft/src/ft_printf/ft_printf.c b/42sh/libft/src/ft_printf/ft_printf.c new file mode 100644 index 00000000..d81e505b --- /dev/null +++ b/42sh/libft/src/ft_printf/ft_printf.c @@ -0,0 +1,37 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_printf.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/07 13:33:27 by jhalford #+# #+# */ +/* Updated: 2017/03/21 15:28:56 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ft_printf.h" + +int ft_printf(const char *format, ...) +{ + va_list ap; + + va_start(ap, format); + return (ft_vdprintf(1, format, ap)); +} + +int ft_dprintf(int fd, const char *format, ...) +{ + va_list ap; + + va_start(ap, format); + return (ft_vdprintf(fd, format, ap)); +} + +int ft_asprintf(char **ret, const char *format, ...) +{ + va_list ap; + + va_start(ap, format); + return (ft_vasprintf(ret, format, ap)); +} diff --git a/42sh/libft/src/ft_printf/ft_printf_color.c b/42sh/libft/src/ft_printf/ft_printf_color.c new file mode 100644 index 00000000..85995f46 --- /dev/null +++ b/42sh/libft/src/ft_printf/ft_printf_color.c @@ -0,0 +1,53 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_printf_color.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/06 18:07:39 by jhalford #+# #+# */ +/* Updated: 2017/03/20 15:51:32 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ft_printf.h" + +t_stos g_colors[] = +{ + {"{red}", FG_RED}, + {"{gre}", FG_GREEN}, + {"{yel}", FG_YELLOW}, + {"{blu}", FG_BLUE}, + {"{mag}", FG_MAGENTA}, + {"{cya}", FG_CYAN}, + {"{bla}", FG_BLACK}, + {"{eoc}", FG_DEFAULT}, + {"{bol}", ON_BOLD}, + {"{und}", ON_UNDERLINED}, + {"{inv}", ON_INVERTED}, + {NULL, NULL}, +}; + +void ft_printf_color(char **final, char **str, va_list ap) +{ + int i; + + i = 0; + if (ft_strncmp(*str, "{ran}", 5) == 0) + { + i = va_arg(ap, int) % 6; + *final = ft_strjoin(*final, g_colors[i].val); + *str += 5; + return ; + } + while (g_colors[i].key) + { + if (ft_strncmp(*str, g_colors[i].key, 5) == 0) + { + *final = ft_strjoin(*final, g_colors[i].val); + *str += 5; + return ; + } + i++; + } +} diff --git a/42sh/libft/src/ft_printf/ft_printf_parse.c b/42sh/libft/src/ft_printf/ft_printf_parse.c new file mode 100644 index 00000000..14797fbf --- /dev/null +++ b/42sh/libft/src/ft_printf/ft_printf_parse.c @@ -0,0 +1,123 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_parse.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/07 13:33:24 by jhalford #+# #+# */ +/* Updated: 2017/03/20 15:55:08 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ft_printf.h" + +static void ft_printf_parse_flags(t_fmt *fmt, char **format) +{ + int i; + char *str; + + i = 0; + str = *format; + while (str[i]) + { + if (ft_strchr(ALL_FLAGS, (int)str[i])) + { + if (!ft_strchr(fmt->flags, (int)str[i])) + ft_strncat(fmt->flags, str + i, 1); + } + else + break ; + i++; + } + *format += i; +} + +static void ft_printf_parse_width(t_fmt *fmt, char **format, va_list ap) +{ + int i; + char buf[10]; + char *str; + + i = 0; + str = *format; + if (str[i] == '*') + { + i++; + fmt->width = va_arg(ap, int); + } + else + { + ft_strcpy(buf, "0"); + while (ft_isdigit((int)(str[i]))) + ft_strncat(buf, str + i++, 1); + fmt->width = ft_atoi(buf); + } + *format += i; +} + +static void ft_printf_parse_precision(t_fmt *fmt, char **format, va_list ap) +{ + int i; + char buf[10]; + char *str; + + i = 0; + str = *format; + if (str[i] == '.') + { + if (str[++i] == '*') + { + i++; + fmt->precision = va_arg(ap, int); + } + else + { + ft_strcpy(buf, "0"); + while (ft_isdigit(str[i])) + ft_strncat(buf, str + i++, 1); + fmt->precision = ft_atoi(buf); + } + } + *format += i; +} + +static void ft_printf_parse_modifiers(t_fmt *fmt, char **format) +{ + char *str; + + str = *format; + if (str[0] == 'h' && str[1] == 'h') + ft_strcpy(fmt->modifier, "hh"); + else if (str[0] == 'h' && str[1] != 'h') + ft_strcpy(fmt->modifier, "h"); + else if (str[0] == 'l' && str[1] == 'l') + ft_strcpy(fmt->modifier, "ll"); + else if (str[0] == 'l' && str[1] != 'l') + ft_strcpy(fmt->modifier, "l"); + else if (str[0] == 'j') + ft_strcpy(fmt->modifier, "j"); + else if (str[0] == 'z') + ft_strcpy(fmt->modifier, "z"); + else + ft_strcpy(fmt->modifier, ""); + *format += ft_strlen(fmt->modifier); +} + +t_fmt *ft_printf_parse(char **format, va_list ap) +{ + t_fmt *fmt; + + fmt = ft_fmt_init(); + ft_printf_parse_flags(fmt, format); + ft_printf_parse_width(fmt, format, ap); + ft_printf_parse_precision(fmt, format, ap); + ft_printf_parse_modifiers(fmt, format); + fmt->conversion = **format; + (*format)++; + ft_fmt_validate_mod(fmt); + ft_fmt_validate_flags(fmt); + ft_fmt_simplify(fmt); + fmt->valid = ft_fmt_validate_conv(fmt) ? 0 : 1; + return (fmt); +} diff --git a/42sh/libft/src/ft_printf/ft_transform.c b/42sh/libft/src/ft_printf/ft_transform.c new file mode 100644 index 00000000..67abd6e1 --- /dev/null +++ b/42sh/libft/src/ft_printf/ft_transform.c @@ -0,0 +1,34 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_transform.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/07 13:33:32 by jhalford #+# #+# */ +/* Updated: 2017/03/20 10:26:37 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ft_printf.h" + +char *ft_transform(t_fmt *fmt, va_list ap) +{ + char *ret; + int i; + + i = 0; + while (fmt->conversion != g_convs[i].id) + i++; + fmt->conv = g_convs[i]; + ret = (*fmt->conv.converter)(fmt, ap); + if (fmt->width > (int)ft_strlen(ret)) + ret = ft_realloc(ret, fmt->width + 5); + else + ret = ft_realloc(ret, ft_strlen(ret) + 3); + if (ft_strchr(fmt->flags, '-')) + ft_pad_right(ret, fmt); + else + ft_pad_left(ret, fmt); + return (ret); +} diff --git a/42sh/libft/src/ft_printf/ft_vprintf.c b/42sh/libft/src/ft_printf/ft_vprintf.c new file mode 100644 index 00000000..09ba322c --- /dev/null +++ b/42sh/libft/src/ft_printf/ft_vprintf.c @@ -0,0 +1,85 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_vprintf.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/20 15:52:57 by jhalford #+# #+# */ +/* Updated: 2017/03/22 17:22:30 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ft_printf.h" + +t_conv g_convs[] = +{ + {'d', "0- +", "0123456789", &ft_signed_conversion, NULL}, + {'i', "0- +", "0123456789", &ft_signed_conversion, NULL}, + {'u', "0-", "0123456789", &ft_unsigned_conversion, NULL}, + {'o', "#0-", "01234567", &ft_unsigned_conversion, &ft_pad_sharp_o}, + {'x', "#0-", "0123456789abcdef", &ft_unsigned_conversion, &ft_pad_sharp_xb}, + {'X', "#0-", "0123456789ABCDEF", &ft_unsigned_conversion, &ft_pad_sharp_xb}, + {'b', "#0-", "01", &ft_unsigned_conversion, &ft_pad_sharp_xb}, + {'s', "-", "", &ft_str_conversion, NULL}, + {'c', "-", "", &ft_char_conversion, NULL}, +}; + +int ft_vdprintf(int fd, const char *format, va_list ap) +{ + char *ret; + char size; + + ret = NULL; + size = ft_vasprintf(&ret, format, ap); + if (size != -1) + ft_putstr_fd(ret, fd); + ft_strdel(&ret); + return (size); +} + +int ft_vasprintf(char **ret, const char *format, va_list ap) +{ + char *str; + char *tmp; + char *final; + + str = (char *)format; + final = ft_strnew(1); + while (*str) + { + tmp = final; + if (*str == '{') + ft_printf_color(&final, &str, ap); + else if (*str == '%') + { + if (ft_fmtcalc(&final, &str, ap)) + return (-1); + } + else if (!(final = ft_strjoin(final, (char[]){*str++, 0}))) + return (-1); + ft_strdel(&tmp); + } + *ret = final; + return (ft_strlen(final)); +} + +int ft_fmtcalc(char **final, char **str, va_list ap) +{ + t_fmt *fmt; + char *transform; + + *str += 1; + if (!(fmt = ft_printf_parse(str, ap))) + return (1); + if (!fmt->valid) + ft_strncat(*final, &fmt->conversion, 1); + else + { + transform = ft_transform(fmt, ap); + *final = ft_strjoin(*final, transform); + ft_strdel(&transform); + } + free(fmt); + return (0); +} diff --git a/42sh/libft/src/ft_printf/lib_fmt.c b/42sh/libft/src/ft_printf/lib_fmt.c new file mode 100644 index 00000000..28b7313d --- /dev/null +++ b/42sh/libft/src/ft_printf/lib_fmt.c @@ -0,0 +1,49 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* lib_fmt.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/07 13:33:35 by jhalford #+# #+# */ +/* Updated: 2017/03/21 15:42:19 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ft_printf.h" + +t_fmt *ft_fmt_init(void) +{ + t_fmt *fmt; + + fmt = (t_fmt *)ft_malloc(sizeof(t_fmt) + 1); + ft_bzero(fmt->flags, 6); + ft_bzero(fmt->modifier, 3); + fmt->conversion = '\0'; + fmt->width = 0; + fmt->precision = 0; + fmt->valid = 0; + return (fmt); +} + +void ft_fmt_print(t_fmt *fmt) +{ + ft_putendl("\n---"); + ft_putstr("valid: "); + ft_putnbr(fmt->valid); + ft_putendl(""); + ft_putstr("conv.: "); + ft_putchar(fmt->conversion); + ft_putendl(""); + ft_putstr("flags: "); + ft_putendl(fmt->flags); + ft_putstr("width: "); + ft_putnbr(fmt->width); + ft_putendl(""); + ft_putstr("prec.: "); + ft_putnbr(fmt->precision); + ft_putendl(""); + ft_putstr("modifier: "); + ft_putendl(fmt->modifier); + ft_putendl("---"); +} diff --git a/42sh/libft/src/ft_printf/lib_fmt_error.c b/42sh/libft/src/ft_printf/lib_fmt_error.c new file mode 100644 index 00000000..a10954ff --- /dev/null +++ b/42sh/libft/src/ft_printf/lib_fmt_error.c @@ -0,0 +1,47 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* lib_fmt_error.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/07 13:33:38 by jhalford #+# #+# */ +/* Updated: 2016/11/07 17:22:41 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ft_printf.h" + +void ft_fmt_error_conv(char conv) +{ + ft_putstr("Warning: invalid or unsupported conversion specifier '"); + ft_putchar(conv); + ft_putendl("'"); +} + +void ft_fmt_error_mod_conv(char *mod, char conv) +{ + ft_putstr("warning: length modifier '"); + ft_putstr(mod); + ft_putstr("' results in undefined behaviour or no effect with '"); + ft_putchar(conv); + ft_putendl("' conversion specifier"); +} + +void ft_fmt_error_flag_conv(char flag, char conv) +{ + ft_putstr("warning: flag '"); + ft_putchar(flag); + ft_putstr("' results in undefined behaviour with '"); + ft_putchar(conv); + ft_putendl("' conversion specifier"); +} + +void ft_fmt_error_flag_flag(char flag1, char flag2) +{ + ft_putstr("warning: flag '"); + ft_putchar(flag1); + ft_putstr("' is ignored when flag '"); + ft_putchar(flag2); + ft_putendl("' is present"); +} diff --git a/42sh/libft/src/ft_printf/lib_pad.c b/42sh/libft/src/ft_printf/lib_pad.c new file mode 100644 index 00000000..57da1c1b --- /dev/null +++ b/42sh/libft/src/ft_printf/lib_pad.c @@ -0,0 +1,42 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* lib_pad.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/07 13:33:45 by jhalford #+# #+# */ +/* Updated: 2017/02/18 13:14:30 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ft_printf.h" + +void ft_pad_right(char *str, t_fmt *fmt) +{ + if (ft_strchr(fmt->flags, '#')) + (fmt->conv.sharp_func)(str, fmt); + while ((int)ft_strlen(str) < fmt->width) + ft_strcat(str, " "); +} + +void ft_pad_left(char *str, t_fmt *fmt) +{ + char sign; + + sign = 0; + if (str[0] == '-' || str[0] == '+' || str[0] == ' ') + { + sign = str[0]; + str++; + } + if (ft_strchr(fmt->flags, '0')) + while ((int)ft_strlen(str) < fmt->width - (sign ? 1 : 0)) + ft_strcatf(str, "0"); + if (sign) + str--; + if (ft_strchr(fmt->flags, '#')) + (fmt->conv.sharp_func)(str, fmt); + while ((int)ft_strlen(str) < fmt->width) + ft_strcatf(str, " "); +} diff --git a/42sh/libft/src/ft_printf/lib_pad_sharp.c b/42sh/libft/src/ft_printf/lib_pad_sharp.c new file mode 100644 index 00000000..5d065581 --- /dev/null +++ b/42sh/libft/src/ft_printf/lib_pad_sharp.c @@ -0,0 +1,44 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* lib_pad_sharp.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/07 13:33:48 by jhalford #+# #+# */ +/* Updated: 2017/03/20 15:54:47 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ft_printf.h" + +void ft_pad_sharp_o(char *str, t_fmt *fmt) +{ + char buf[100]; + + (void)fmt; + ft_bzero(buf, 100); + if (str[0] != '0') + ft_strcatf(buf, "0"); +} + +void ft_pad_sharp_xb(char *str, t_fmt *fmt) +{ + char start[3]; + + start[0] = '0'; + start[1] = fmt->conversion; + start[2] = 0; + if (str[0] == '0') + { + if (str[1] == '0') + str[1] = fmt->conversion; + else + { + str[0] = fmt->conversion; + ft_strcatf(str, "0"); + } + } + else + ft_strcatf(str, start); +} diff --git a/42sh/libft/src/get_next_line/get_next_line.c b/42sh/libft/src/get_next_line/get_next_line.c new file mode 100644 index 00000000..3eed0dee --- /dev/null +++ b/42sh/libft/src/get_next_line/get_next_line.c @@ -0,0 +1,89 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* get_next_line.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/15 13:12:06 by jhalford #+# #+# */ +/* Updated: 2017/03/21 15:43:51 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "get_next_line.h" + +static int ft_fdcmp(t_save *a, int *b) +{ + return (a->fd - *b); +} + +static void ft_gnlfree(void *a, size_t size) +{ + (void)size; + ft_strdel(&((t_save*)a)->str); + free(a); +} + +static t_list *ft_newfd(t_list **head, int fd) +{ + t_save new; + + new.fd = fd; + new.str = ft_memalloc((BUFF_SIZE > 0 ? BUFF_SIZE : 0) + 1); + ft_lstadd(head, ft_lstnew(&new, sizeof(t_save))); + return (*head); +} + +static int ft_loop_read(int fd, char **line, char *save) +{ + char buf[BUFF_SIZE + 1]; + char *pos; + char *tmp; + int ret; + + while ((ret = read(fd, buf, BUFF_SIZE)) > 0) + { + buf[ret] = 0; + tmp = *line; + if ((pos = ft_strchr(buf, '\n'))) + { + ft_strcpy(save, pos + 1); + *pos = 0; + } + if (!(*line = ft_strjoin(*line, buf))) + return (-1); + ft_strdel(&tmp); + if (pos) + return (1); + } + if (ret < 0) + return (-1); + return (**line ? 1 : 0); +} + +int get_next_line(int const fd, char **line) +{ + static t_list *head; + t_list *tmp; + char *pos; + char *save; + int ret; + + if (fd < 0 || !line) + return (-1); + if (!(tmp = ft_lst_find(head, (void *)&fd, &ft_fdcmp))) + tmp = ft_newfd(&head, fd); + save = ((t_save*)tmp->content)->str; + if (!(*line = ft_strdup(save))) + return (-1); + ft_bzero(save, BUFF_SIZE + 1); + if ((pos = ft_strchr(*line, '\n'))) + { + ft_strcpy(save, pos + 1); + *pos = 0; + return (1); + } + if (!(ret = ft_loop_read(fd, line, save))) + ft_lst_delif(&head, (int *)&fd, ft_fdcmp, &ft_gnlfree); + return (ret); +} diff --git a/42sh/libft/src/lst/ft_id.c b/42sh/libft/src/lst/ft_id.c new file mode 100644 index 00000000..d5bac3fb --- /dev/null +++ b/42sh/libft/src/lst/ft_id.c @@ -0,0 +1,18 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_id.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/04 11:08:55 by jhalford #+# #+# */ +/* Updated: 2017/03/07 22:43:40 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +t_list *ft_id(t_list *a) +{ + return (a); +} diff --git a/42sh/libft/src/lst/ft_lst_at.c b/42sh/libft/src/lst/ft_lst_at.c new file mode 100644 index 00000000..0013ce45 --- /dev/null +++ b/42sh/libft/src/lst/ft_lst_at.c @@ -0,0 +1,28 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_list_at.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/08/14 13:18:48 by jhalford #+# #+# */ +/* Updated: 2016/12/12 14:58:37 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "lst.h" + +t_list *ft_lst_at(t_list *list, unsigned int nbr) +{ + unsigned int i; + + if (!list) + return (NULL); + i = 0; + while (i < nbr && list) + { + list = list->next; + i++; + } + return (list); +} diff --git a/42sh/libft/src/lst/ft_lst_bfree.c b/42sh/libft/src/lst/ft_lst_bfree.c new file mode 100644 index 00000000..67a308ae --- /dev/null +++ b/42sh/libft/src/lst/ft_lst_bfree.c @@ -0,0 +1,26 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lst_bfree.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/07 16:55:04 by jhalford #+# #+# */ +/* Updated: 2016/12/07 18:07:31 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void ft_lst_bfree(void *ptr, size_t size) +{ + t_list *lst; + + lst = ptr; + (void)size; + if (lst) + { + ft_strdel((char **)&lst->content); + free(lst); + } +} diff --git a/42sh/libft/src/lst/ft_lst_cfree.c b/42sh/libft/src/lst/ft_lst_cfree.c new file mode 100644 index 00000000..e9b8b1dc --- /dev/null +++ b/42sh/libft/src/lst/ft_lst_cfree.c @@ -0,0 +1,20 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lst_cfree.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/04 11:09:10 by jhalford #+# #+# */ +/* Updated: 2016/12/07 16:55:43 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void ft_lst_cfree(void *ptr, size_t size) +{ + (void)size; + if (ptr) + free(ptr); +} diff --git a/42sh/libft/src/lst/ft_lst_delif.c b/42sh/libft/src/lst/ft_lst_delif.c new file mode 100644 index 00000000..768272b5 --- /dev/null +++ b/42sh/libft/src/lst/ft_lst_delif.c @@ -0,0 +1,36 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lst_delif.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/04 11:09:12 by jhalford #+# #+# */ +/* Updated: 2017/03/27 17:45:01 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void ft_lst_delif( + t_list **alst, + void *data_ref, + int (*cmp)(), + void (*del)(void *, size_t)) +{ + t_list *tmp; + t_list **indirect; + + indirect = alst; + while (*indirect) + { + if ((*cmp)((*indirect)->content, data_ref) == 0) + { + tmp = (*indirect); + (*indirect) = (*indirect)->next; + ft_lstdelone(&tmp, del); + } + else + indirect = &(*indirect)->next; + } +} diff --git a/42sh/libft/src/lst/ft_lst_delsub.c b/42sh/libft/src/lst/ft_lst_delsub.c new file mode 100644 index 00000000..b3912fc2 --- /dev/null +++ b/42sh/libft/src/lst/ft_lst_delsub.c @@ -0,0 +1,36 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lst_delsub.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/04 11:09:15 by jhalford #+# #+# */ +/* Updated: 2017/01/12 14:33:28 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void ft_lst_delsub( + t_list **alst, + t_list *sub, + int (*cmp)(), + void (*del)(void *, size_t)) +{ + t_list *tmp; + t_list **indirect; + + indirect = alst; + while (*indirect) + { + if ((*cmp)((*indirect)->content, sub->content) == 0) + { + tmp = *indirect; + (*indirect) = (*indirect)->next; + sub = sub->next; + ft_lstdelone(&tmp, del); + } + indirect = &(*indirect)->next; + } +} diff --git a/42sh/libft/src/lst/ft_lst_filter.c b/42sh/libft/src/lst/ft_lst_filter.c new file mode 100644 index 00000000..f0004126 --- /dev/null +++ b/42sh/libft/src/lst/ft_lst_filter.c @@ -0,0 +1,35 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lst_filter.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/04 11:09:17 by jhalford #+# #+# */ +/* Updated: 2017/03/02 17:47:26 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +t_list *ft_lst_filter( + t_list *lst, + void const *data_ref, + t_list *(*f)(t_list *elem, void const *)) +{ + t_list *out; + t_list *elem; + + out = NULL; + while (lst) + { + if (f) + elem = (*f)(lst, data_ref); + else + elem = lst; + elem = ft_lstnew(elem->content, elem->content_size); + ft_lsteadd(&out, elem); + lst = lst->next; + } + return (out); +} diff --git a/42sh/libft/src/lst/ft_lst_find.c b/42sh/libft/src/lst/ft_lst_find.c new file mode 100644 index 00000000..3163d3af --- /dev/null +++ b/42sh/libft/src/lst/ft_lst_find.c @@ -0,0 +1,27 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lst_find.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/04 11:09:20 by jhalford #+# #+# */ +/* Updated: 2017/01/10 11:07:37 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +t_list *ft_lst_find(t_list *begin_list, void *data_ref, int (*cmp)()) +{ + t_list *list_ptr; + + list_ptr = begin_list; + while (list_ptr) + { + if ((cmp)(list_ptr->content, data_ref) == 0) + return (list_ptr); + list_ptr = list_ptr->next; + } + return (NULL); +} diff --git a/42sh/libft/src/lst/ft_lst_merge.c b/42sh/libft/src/lst/ft_lst_merge.c new file mode 100644 index 00000000..f8160381 --- /dev/null +++ b/42sh/libft/src/lst/ft_lst_merge.c @@ -0,0 +1,28 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_list_merge.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/08/14 13:50:32 by jhalford #+# #+# */ +/* Updated: 2016/11/04 11:09:24 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void ft_lst_merge(t_list **begin_list1, t_list *begin_list2) +{ + t_list *list_ptr; + + if (*begin_list1) + { + list_ptr = *begin_list1; + while (list_ptr->next) + list_ptr = list_ptr->next; + list_ptr->next = begin_list2; + } + else + *begin_list1 = begin_list2; +} diff --git a/42sh/libft/src/lst/ft_lst_order_delsub.c b/42sh/libft/src/lst/ft_lst_order_delsub.c new file mode 100644 index 00000000..5bf2067c --- /dev/null +++ b/42sh/libft/src/lst/ft_lst_order_delsub.c @@ -0,0 +1,41 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lst_order_delsub.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/04 11:09:25 by jhalford #+# #+# */ +/* Updated: 2016/11/04 12:01:47 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void ft_lst_order_delsub( + t_list **alst, + t_list *sub, + int (*cmp)(), + void (*del)(void *, size_t)) +{ + t_list *tmp; + t_list **indirect; + + indirect = alst; + while (*indirect) + { + if ((*cmp)((*indirect)->content, sub->content) > 0) + { + sub = sub->next; + continue ; + } + if ((*cmp)((*indirect)->content, sub->content) == 0) + { + tmp = *indirect; + (*indirect) = (*indirect)->next; + ft_lstdelone(&tmp, del); + sub = sub->next; + } + indirect = &(*indirect)->next; + } +} diff --git a/42sh/libft/src/lst/ft_lst_print.c b/42sh/libft/src/lst/ft_lst_print.c new file mode 100644 index 00000000..0ff1d1a6 --- /dev/null +++ b/42sh/libft/src/lst/ft_lst_print.c @@ -0,0 +1,25 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lst_print.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/04 11:09:27 by jhalford #+# #+# */ +/* Updated: 2017/03/26 21:25:21 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void ft_lst_print(t_list *list, void (*printer)()) +{ + while (list) + { + ft_putstr("["); + (*printer)(list->content); + ft_putstr("]->"); + list = list->next; + } + ft_putendl("X\n"); +} diff --git a/42sh/libft/src/lst/ft_lst_print2.c b/42sh/libft/src/lst/ft_lst_print2.c new file mode 100644 index 00000000..875167d1 --- /dev/null +++ b/42sh/libft/src/lst/ft_lst_print2.c @@ -0,0 +1,37 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lst_print2.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/04 11:09:29 by jhalford #+# #+# */ +/* Updated: 2016/11/04 11:09:29 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void ft_lst_print2(t_list *list, void (*printer)()) +{ + t_list *list2; + + while (list) + { + ft_putendl("---"); + list2 = *(t_list**)list->content; + while (list2) + { + ft_putstr("["); + (*printer)(*(int *)list2->content); + ft_putstr("]->"); + list2 = list2->next; + } + ft_putendl("X"); + ft_putendl("---"); + ft_putendl(" |"); + ft_putendl(" V"); + list = list->next; + } + ft_putendl(" X\n"); +} diff --git a/42sh/libft/src/lst/ft_lst_removeif.c b/42sh/libft/src/lst/ft_lst_removeif.c new file mode 100644 index 00000000..b82f57c2 --- /dev/null +++ b/42sh/libft/src/lst/ft_lst_removeif.c @@ -0,0 +1,33 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lst_removeif.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/04 11:09:30 by jhalford #+# #+# */ +/* Updated: 2017/03/13 15:31:13 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +t_list *ft_lst_removeif(t_list **alst, void *data_ref, int (*cmp)()) +{ + t_list *tmp; + t_list **indirect; + + indirect = alst; + while (*indirect) + { + if ((*cmp)((*indirect)->content, data_ref) == 0) + { + tmp = (*indirect); + (*indirect) = (*indirect)->next; + tmp->next = NULL; + return (tmp); + } + indirect = &(*indirect)->next; + } + return (NULL); +} diff --git a/42sh/libft/src/lst/ft_lst_reverse.c b/42sh/libft/src/lst/ft_lst_reverse.c new file mode 100644 index 00000000..7765d598 --- /dev/null +++ b/42sh/libft/src/lst/ft_lst_reverse.c @@ -0,0 +1,29 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_list_reverse.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/08/14 13:20:13 by jhalford #+# #+# */ +/* Updated: 2017/03/08 00:31:33 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void ft_lst_reverse(t_list **begin_list) +{ + t_list *new_start; + t_list *tmp; + + new_start = NULL; + while (*begin_list) + { + tmp = (*begin_list)->next; + (*begin_list)->next = new_start; + new_start = *begin_list; + *begin_list = tmp; + } + *begin_list = new_start; +} diff --git a/42sh/libft/src/lst/ft_lst_size.c b/42sh/libft/src/lst/ft_lst_size.c new file mode 100644 index 00000000..1f8c03b8 --- /dev/null +++ b/42sh/libft/src/lst/ft_lst_size.c @@ -0,0 +1,30 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lst_size.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/04 11:09:35 by jhalford #+# #+# */ +/* Updated: 2016/11/04 11:09:36 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +int ft_lstsize(t_list *lst) +{ + int i; + + i = 0; + if (lst) + { + i = 1; + while (lst->next) + { + lst = lst->next; + i++; + } + } + return (i); +} diff --git a/42sh/libft/src/lst/ft_lst_sorted_insert.c b/42sh/libft/src/lst/ft_lst_sorted_insert.c new file mode 100644 index 00000000..f4821326 --- /dev/null +++ b/42sh/libft/src/lst/ft_lst_sorted_insert.c @@ -0,0 +1,39 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lst_sorted_insert.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/04 11:09:39 by jhalford #+# #+# */ +/* Updated: 2016/11/04 11:09:39 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void ft_lst_sorted_insert(t_list **begin_list, t_list *insert, int (*cmp)()) +{ + t_list *link; + + link = *begin_list; + if (!link || (*cmp)(insert->content, link->content) < 0) + { + *begin_list = insert; + insert->next = link ? link : NULL; + return ; + } + while (link->next) + { + if ((*cmp)(insert->content, link->content) > 0 + && (*cmp)(insert->content, link->next->content) <= 0) + { + insert->next = link->next; + link->next = insert; + return ; + } + link = link->next; + } + link->next = insert; + insert->next = NULL; +} diff --git a/42sh/libft/src/lst/ft_lst_sorted_merge.c b/42sh/libft/src/lst/ft_lst_sorted_merge.c new file mode 100644 index 00000000..38308849 --- /dev/null +++ b/42sh/libft/src/lst/ft_lst_sorted_merge.c @@ -0,0 +1,44 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lst_sorted_merge.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/04 11:09:40 by jhalford #+# #+# */ +/* Updated: 2016/11/04 11:09:40 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void ft_lst_sorted_merge( + t_list **begin_list1, + t_list *begin_list2, + int (*cmp)()) +{ + t_list *tail; + t_list *head1; + t_list *head2; + int comp; + + if (!*begin_list1 || !begin_list2) + { + *begin_list1 = begin_list2 ? begin_list2 : *begin_list1; + return ; + } + comp = (*cmp)(begin_list2->content, (*begin_list1)->content); + head1 = (comp < 0) ? *begin_list1 : (*begin_list1)->next; + head2 = (comp < 0) ? begin_list2->next : begin_list2; + *begin_list1 = (comp < 0) ? begin_list2 : *begin_list1; + tail = *begin_list1; + while (head1 && head2) + { + comp = (*cmp)(head2->content, head1->content); + tail->next = (comp < 0 ? head2 : head1); + head1 = comp < 0 ? head1 : head1->next; + head2 = comp < 0 ? head2->next : head2; + tail = tail->next; + } + tail->next = head2 ? head2 : head1; +} diff --git a/42sh/libft/src/lst/ft_lstadd.c b/42sh/libft/src/lst/ft_lstadd.c new file mode 100644 index 00000000..1d465dd1 --- /dev/null +++ b/42sh/libft/src/lst/ft_lstadd.c @@ -0,0 +1,22 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lstadd.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/03 14:57:13 by jhalford #+# #+# */ +/* Updated: 2017/03/08 00:19:43 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void ft_lstadd(t_list **alst, t_list *new) +{ + if (new) + { + new->next = *alst; + *alst = new; + } +} diff --git a/42sh/libft/src/lst/ft_lstdel.c b/42sh/libft/src/lst/ft_lstdel.c new file mode 100644 index 00000000..720dd7e9 --- /dev/null +++ b/42sh/libft/src/lst/ft_lstdel.c @@ -0,0 +1,21 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lstdel.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/03 15:18:57 by jhalford #+# #+# */ +/* Updated: 2017/03/26 21:56:50 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void ft_lstdel(t_list **alst, void (*del)(void *, size_t)) +{ + if (!(alst && *alst && del)) + return ; + ft_lstdel(&(*alst)->next, del); + ft_lstdelone(alst, del); +} diff --git a/42sh/libft/src/lst/ft_lstdelone.c b/42sh/libft/src/lst/ft_lstdelone.c new file mode 100644 index 00000000..e550e0f3 --- /dev/null +++ b/42sh/libft/src/lst/ft_lstdelone.c @@ -0,0 +1,24 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lstdelone.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/05 13:39:33 by jhalford #+# #+# */ +/* Updated: 2017/03/26 21:24:36 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void ft_lstdelone(t_list **alst, void (*del)(void *, size_t)) +{ + if (alst && *alst) + { + if (del) + (*del)((*alst)->content, (*alst)->content_size); + free(*alst); + *alst = NULL; + } +} diff --git a/42sh/libft/src/lst/ft_lsteadd.c b/42sh/libft/src/lst/ft_lsteadd.c new file mode 100644 index 00000000..142f9660 --- /dev/null +++ b/42sh/libft/src/lst/ft_lsteadd.c @@ -0,0 +1,28 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lsteadd.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/03 14:57:17 by jhalford #+# #+# */ +/* Updated: 2017/03/13 15:37:23 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void ft_lsteadd(t_list **alst, t_list *new) +{ + t_list *lst; + + lst = *alst; + if (lst) + { + while (lst->next) + lst = lst->next; + lst->next = new; + } + else + *alst = new; +} diff --git a/42sh/libft/src/lst/ft_lstiter.c b/42sh/libft/src/lst/ft_lstiter.c new file mode 100644 index 00000000..217f803c --- /dev/null +++ b/42sh/libft/src/lst/ft_lstiter.c @@ -0,0 +1,24 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lstiter.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/03 14:57:19 by jhalford #+# #+# */ +/* Updated: 2017/03/11 16:17:43 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +int ft_lstiter(t_list *lst, int (*f)()) +{ + while (lst) + { + if ((*f)(lst->content)) + return (1); + lst = lst->next; + } + return (0); +} diff --git a/42sh/libft/src/lst/ft_lstlast.c b/42sh/libft/src/lst/ft_lstlast.c new file mode 100644 index 00000000..addae8fc --- /dev/null +++ b/42sh/libft/src/lst/ft_lstlast.c @@ -0,0 +1,21 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lstlast.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/04 11:09:48 by jhalford #+# #+# */ +/* Updated: 2017/02/09 20:46:28 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +t_list *ft_lstlast(t_list *lst) +{ + if (lst) + while (lst->next) + lst = lst->next; + return (lst); +} diff --git a/42sh/libft/src/lst/ft_lstmap.c b/42sh/libft/src/lst/ft_lstmap.c new file mode 100644 index 00000000..e0edbbaa --- /dev/null +++ b/42sh/libft/src/lst/ft_lstmap.c @@ -0,0 +1,26 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lstmap.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/03 14:57:21 by jhalford #+# #+# */ +/* Updated: 2017/03/21 15:42:19 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +t_list *ft_lstmap(t_list *lst, void *(*f)(void *)) +{ + t_list *elem; + + if (!lst) + return (NULL); + if (!(elem = (t_list *)ft_malloc(sizeof(*elem)))) + return (NULL); + elem->content = (*f)(lst->content); + elem->next = ft_lstmap(lst->next, f); + return (elem); +} diff --git a/42sh/libft/src/lst/ft_lstnadd.c b/42sh/libft/src/lst/ft_lstnadd.c new file mode 100644 index 00000000..3f542fad --- /dev/null +++ b/42sh/libft/src/lst/ft_lstnadd.c @@ -0,0 +1,35 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lstnadd.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/04 11:09:51 by jhalford #+# #+# */ +/* Updated: 2016/11/04 11:09:52 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void ft_lstnadd(t_list **alst, t_list *new, int n) +{ + t_list *lst; + int i; + + lst = *alst; + if (lst) + { + i = 0; + while (lst->next && i < n) + { + lst = lst->next; + i++; + } + while (lst->next) + lst = lst->next; + lst->next = new; + } + else + *alst = new; +} diff --git a/42sh/libft/src/lst/ft_lstnew.c b/42sh/libft/src/lst/ft_lstnew.c new file mode 100644 index 00000000..e72d9ab7 --- /dev/null +++ b/42sh/libft/src/lst/ft_lstnew.c @@ -0,0 +1,27 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lstnew.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/29 15:57:38 by jhalford #+# #+# */ +/* Updated: 2017/03/21 15:43:51 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +t_list *ft_lstnew(void const *content, size_t content_size) +{ + t_list *new; + + if (!(new = (t_list *)ft_malloc(sizeof(*new)))) + return (NULL); + new->next = NULL; + new->content_size = content_size; + new->content = ft_memalloc(content_size + 1); + if (content) + ft_memcpy(new->content, content, content_size); + return (new); +} diff --git a/42sh/libft/src/lst/ft_lstnew_range.c b/42sh/libft/src/lst/ft_lstnew_range.c new file mode 100644 index 00000000..26632a3b --- /dev/null +++ b/42sh/libft/src/lst/ft_lstnew_range.c @@ -0,0 +1,28 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lstnew_range.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/04 11:09:54 by jhalford #+# #+# */ +/* Updated: 2016/11/04 11:09:54 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +t_list *ft_lstnew_range(int a, int b) +{ + t_list *lst; + + if (a >= b) + return (NULL); + lst = NULL; + while (a < b) + { + b--; + ft_lstadd(&lst, ft_lstnew(&b, sizeof(int))); + } + return (lst); +} diff --git a/42sh/libft/src/lst/ft_lstsort.c b/42sh/libft/src/lst/ft_lstsort.c new file mode 100644 index 00000000..950d6fd3 --- /dev/null +++ b/42sh/libft/src/lst/ft_lstsort.c @@ -0,0 +1,38 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lstsort.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/04 11:09:58 by jhalford #+# #+# */ +/* Updated: 2017/01/09 12:29:58 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void ft_lstsort(t_list **begin_list, int (*cmp)()) +{ + t_list **indirect; + t_list *tmp; + t_list *tmp2; + + indirect = begin_list; + if (!*begin_list) + return ; + while (*indirect && (*indirect)->next) + { + if ((*cmp)((*indirect)->content, (*indirect)->next->content) > 0) + { + tmp = *indirect; + tmp2 = (*indirect)->next; + (*indirect)->next = (*indirect)->next->next; + *indirect = tmp2; + (*indirect)->next = tmp; + indirect = begin_list; + } + else + indirect = &(*indirect)->next; + } +} diff --git a/42sh/libft/src/lst/pop.c b/42sh/libft/src/lst/pop.c new file mode 100644 index 00000000..05beda83 --- /dev/null +++ b/42sh/libft/src/lst/pop.c @@ -0,0 +1,27 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* pop.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/04 11:09:56 by jhalford #+# #+# */ +/* Updated: 2017/03/26 22:14:17 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +int pop(t_list **lst) +{ + t_list *top; + int item; + + if (!(lst && *lst)) + return (0); + top = *lst; + item = top ? *(int*)top->content : 0; + *lst = (*lst)->next; + ft_lstdelone(&top, ft_lst_cfree); + return (item); +} diff --git a/42sh/libft/src/lst/push.c b/42sh/libft/src/lst/push.c new file mode 100644 index 00000000..111b3505 --- /dev/null +++ b/42sh/libft/src/lst/push.c @@ -0,0 +1,19 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* push.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/09 15:59:39 by jhalford #+# #+# */ +/* Updated: 2017/03/02 20:59:42 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +t_list *push(t_list **stack, int elem) +{ + ft_lstadd(stack, ft_lstnew(&elem, sizeof(elem))); + return (*stack); +} diff --git a/42sh/libft/src/lst/top.c b/42sh/libft/src/lst/top.c new file mode 100644 index 00000000..2c3186e2 --- /dev/null +++ b/42sh/libft/src/lst/top.c @@ -0,0 +1,18 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* top.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/24 20:04:27 by jhalford #+# #+# */ +/* Updated: 2017/03/24 20:09:06 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +int top(t_list *top) +{ + return (top ? *(int*)top->content : 0); +} diff --git a/42sh/libft/src/math/ft_addrcmp.c b/42sh/libft/src/math/ft_addrcmp.c new file mode 100644 index 00000000..5c430c71 --- /dev/null +++ b/42sh/libft/src/math/ft_addrcmp.c @@ -0,0 +1,18 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_addrcmp.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/14 15:59:10 by jhalford #+# #+# */ +/* Updated: 2017/01/11 16:28:40 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +int ft_addrcmp(void *a, void *b) +{ + return (a - b); +} diff --git a/42sh/libft/src/math/ft_ilen.c b/42sh/libft/src/math/ft_ilen.c new file mode 100644 index 00000000..bbce37b5 --- /dev/null +++ b/42sh/libft/src/math/ft_ilen.c @@ -0,0 +1,23 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_ilen.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/07 13:53:53 by jhalford #+# #+# */ +/* Updated: 2017/02/18 15:41:20 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +size_t ft_ilen(int n) +{ + size_t i; + + i = 1; + while (n /= 10) + i++; + return (i); +} diff --git a/42sh/libft/src/math/ft_ilen_base.c b/42sh/libft/src/math/ft_ilen_base.c new file mode 100644 index 00000000..3c6f9ae4 --- /dev/null +++ b/42sh/libft/src/math/ft_ilen_base.c @@ -0,0 +1,23 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_ilen_base.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/07 13:53:53 by jhalford #+# #+# */ +/* Updated: 2016/11/07 14:45:28 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +size_t ft_ilen_base(int n, int base) +{ + size_t i; + + i = 1; + while (n /= base) + i++; + return (i); +} diff --git a/42sh/libft/src/math/ft_itoa.c b/42sh/libft/src/math/ft_itoa.c new file mode 100644 index 00000000..b1342f1c --- /dev/null +++ b/42sh/libft/src/math/ft_itoa.c @@ -0,0 +1,49 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_itoa.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/03 14:57:10 by jhalford #+# #+# */ +/* Updated: 2017/03/07 12:08:47 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +static size_t ft_size(int n) +{ + size_t i; + + i = 1; + while (n /= 10) + i++; + return (i); +} + +char *ft_itoa(int n) +{ + int i; + char *str; + int neg; + + i = 0; + str = ft_strnew(ft_size(n) + 1); + neg = FT_NEG(n) ? 1 : 0; + if (n == 0) + { + str[i++] = '0'; + str[i] = '\0'; + return (str); + } + while (n) + { + str[i++] = FT_ABS(n % 10) + '0'; + n /= 10; + } + if (neg) + str[i++] = '-'; + str[i] = '\0'; + return (ft_strrev(str)); +} diff --git a/42sh/libft/src/math/ft_itoa_base.c b/42sh/libft/src/math/ft_itoa_base.c new file mode 100644 index 00000000..edc60b46 --- /dev/null +++ b/42sh/libft/src/math/ft_itoa_base.c @@ -0,0 +1,51 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_itoa_base.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/07 13:52:51 by jhalford #+# #+# */ +/* Updated: 2017/01/22 16:38:53 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +static char *ft_flags(char *str, int *i, char *flags, int neg) +{ + if (neg) + str[*i++] = '-'; + else if (ft_strchr(flags, '+')) + str[*i++] = '+'; + else if (ft_strchr(flags, ' ')) + str[*i++] = ' '; + return (str); +} + +char *ft_itoa_base(int nbr, char *base, char *flags) +{ + int i; + int neg; + int base_size; + char *str; + + i = 0; + base_size = ft_strlen(base); + str = ft_strnew(ft_ilen_base(nbr, base_size) + 1); + neg = FT_NEG(nbr); + if (nbr == 0) + { + str[i++] = '0'; + str[i] = '\0'; + return (str); + } + while (nbr) + { + str[i++] = base[FT_ABS(nbr % base_size)]; + nbr = nbr / base_size; + } + str = ft_flags(str, &i, flags, neg); + str[i] = '\0'; + return (ft_strrev(str)); +} diff --git a/42sh/libft/src/math/ft_lllen.c b/42sh/libft/src/math/ft_lllen.c new file mode 100644 index 00000000..4ef07cc8 --- /dev/null +++ b/42sh/libft/src/math/ft_lllen.c @@ -0,0 +1,23 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lllen.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/07 13:52:35 by jhalford #+# #+# */ +/* Updated: 2016/11/07 14:45:40 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +size_t ft_lllen(long long n) +{ + size_t i; + + i = 1; + while (n /= 10) + i++; + return (i); +} diff --git a/42sh/libft/src/math/ft_lllen_base.c b/42sh/libft/src/math/ft_lllen_base.c new file mode 100644 index 00000000..74b934eb --- /dev/null +++ b/42sh/libft/src/math/ft_lllen_base.c @@ -0,0 +1,23 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lllen_base.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/07 13:52:35 by jhalford #+# #+# */ +/* Updated: 2016/11/07 14:46:15 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +size_t ft_lllen_base(long long n, int base) +{ + size_t i; + + i = 1; + while (n /= base) + i++; + return (i); +} diff --git a/42sh/libft/src/math/ft_lltoa_base.c b/42sh/libft/src/math/ft_lltoa_base.c new file mode 100644 index 00000000..69d31aff --- /dev/null +++ b/42sh/libft/src/math/ft_lltoa_base.c @@ -0,0 +1,52 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lltoa_base.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/07 13:10:42 by jhalford #+# #+# */ +/* Updated: 2017/02/18 15:23:41 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +static char *ft_flags(char *str, int *i, char *flags, int neg) +{ + if (neg) + str[(*i)++] = '-'; + else if (ft_strchr(flags, '+')) + str[(*i)++] = '+'; + else if (ft_strchr(flags, ' ')) + str[(*i)++] = ' '; + return (str); +} + +char *ft_lltoa_base(long long nbr, char *base, char *flags) +{ + int i; + int neg; + int base_size; + char *str; + + i = 0; + base_size = ft_strlen(base); + str = ft_strnew(ft_lllen_base(nbr, base_size) + 1); + neg = FT_NEG(nbr); + if (nbr == 0) + { + str[i++] = '0'; + str[i] = '\0'; + return (str); + } + while (nbr) + { + str[i++] = base[FT_ABS(nbr % base_size)]; + nbr = nbr / base_size; + } + str = ft_flags(str, &i, flags, neg); + str[i] = 0; + ft_strrev(str); + return (str); +} diff --git a/42sh/libft/src/math/ft_uilen.c b/42sh/libft/src/math/ft_uilen.c new file mode 100644 index 00000000..9e87ca1f --- /dev/null +++ b/42sh/libft/src/math/ft_uilen.c @@ -0,0 +1,23 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_uilen.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/07 13:52:35 by jhalford #+# #+# */ +/* Updated: 2016/11/07 13:54:41 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +size_t ft_uilen(unsigned int n) +{ + size_t i; + + i = 1; + while (n /= 10) + i++; + return (i); +} diff --git a/42sh/libft/src/math/ft_uitoa_base.c b/42sh/libft/src/math/ft_uitoa_base.c new file mode 100644 index 00000000..a09cb11e --- /dev/null +++ b/42sh/libft/src/math/ft_uitoa_base.c @@ -0,0 +1,47 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_uitoa_base.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/07 13:08:10 by jhalford #+# #+# */ +/* Updated: 2016/11/07 13:10:35 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +static size_t ft_size(unsigned int n, int base) +{ + size_t i; + + i = 1; + while (n /= base) + i++; + return (i); +} + +char *ft_uitoa_base(unsigned int nbr, char *base) +{ + int i; + int base_size; + char *str; + + i = 0; + base_size = ft_strlen(base); + str = ft_strnew(ft_size(nbr, base_size) + 1); + if (nbr == 0) + { + str[i++] = '0'; + str[i] = '\0'; + return (str); + } + while (nbr) + { + str[i++] = base[nbr % base_size]; + nbr = nbr / base_size; + } + str[i] = '\0'; + return (ft_strrev(str)); +} diff --git a/42sh/libft/src/math/ft_ulltoa_base.c b/42sh/libft/src/math/ft_ulltoa_base.c new file mode 100644 index 00000000..5a5a3675 --- /dev/null +++ b/42sh/libft/src/math/ft_ulltoa_base.c @@ -0,0 +1,47 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_ulltoa_base.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/07 13:07:50 by jhalford #+# #+# */ +/* Updated: 2017/02/18 16:07:02 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +static size_t ft_size(unsigned long long n, int base) +{ + size_t i; + + i = 1; + while (n /= base) + i++; + return (i); +} + +char *ft_ulltoa_base(unsigned long long nbr, char *base) +{ + int i; + int base_size; + char *str; + + i = 0; + base_size = ft_strlen(base); + str = ft_strnew(ft_size(nbr, base_size) + 1); + if (nbr == 0) + { + str[i++] = '0'; + str[i] = '\0'; + return (str); + } + while (nbr) + { + str[i++] = base[nbr % base_size]; + nbr = nbr / base_size; + } + str[i] = '\0'; + return (ft_strrev(str)); +} diff --git a/42sh/libft/src/math/id.c b/42sh/libft/src/math/id.c new file mode 100644 index 00000000..e23a5831 --- /dev/null +++ b/42sh/libft/src/math/id.c @@ -0,0 +1,18 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* id.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/20 12:20:59 by jhalford #+# #+# */ +/* Updated: 2017/03/20 12:21:01 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void *id(void *data) +{ + return (data); +} diff --git a/42sh/libft/src/mem/ft_bzero.c b/42sh/libft/src/mem/ft_bzero.c new file mode 100644 index 00000000..6f1834b5 --- /dev/null +++ b/42sh/libft/src/mem/ft_bzero.c @@ -0,0 +1,22 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_bzero.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/03 14:56:08 by jhalford #+# #+# */ +/* Updated: 2016/11/03 14:56:09 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void ft_bzero(void *s, size_t n) +{ + size_t i; + + i = -1; + while (++i < n) + *(char *)s++ = 0; +} diff --git a/42sh/libft/src/mem/ft_malloc.c b/42sh/libft/src/mem/ft_malloc.c new file mode 100644 index 00000000..bb1b9b54 --- /dev/null +++ b/42sh/libft/src/mem/ft_malloc.c @@ -0,0 +1,26 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_malloc.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/21 15:45:00 by jhalford #+# #+# */ +/* Updated: 2017/03/23 18:31:10 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void *ft_malloc(size_t size) +{ + void *ptr; + + ptr = malloc(size); + if (!ptr) + { + ft_putstr_fd(strerror(errno), 2); + exit(errno); + } + return (ptr); +} diff --git a/42sh/libft/src/mem/ft_memalloc.c b/42sh/libft/src/mem/ft_memalloc.c new file mode 100644 index 00000000..6a4a1112 --- /dev/null +++ b/42sh/libft/src/mem/ft_memalloc.c @@ -0,0 +1,27 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_memalloc.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/03 14:57:25 by jhalford #+# #+# */ +/* Updated: 2017/03/21 15:43:51 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void *ft_memalloc(size_t size) +{ + void *addr; + size_t i; + + addr = ft_malloc(size); + if (addr == NULL) + return (NULL); + i = -1; + while (++i < size) + ((char *)addr)[i] = 0; + return (addr); +} diff --git a/42sh/libft/src/mem/ft_memccpy.c b/42sh/libft/src/mem/ft_memccpy.c new file mode 100644 index 00000000..ee5d8071 --- /dev/null +++ b/42sh/libft/src/mem/ft_memccpy.c @@ -0,0 +1,27 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_memccpy.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/03 14:57:26 by jhalford #+# #+# */ +/* Updated: 2017/03/06 15:36:13 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void *ft_memccpy(void *dst, const void *src, int c, size_t n) +{ + size_t i; + + i = -1; + while (++i < n) + { + *(char *)dst++ = *(char *)src; + if (*(char *)src++ == c) + return (dst); + } + return (NULL); +} diff --git a/42sh/libft/src/mem/ft_memchr.c b/42sh/libft/src/mem/ft_memchr.c new file mode 100644 index 00000000..96ddf009 --- /dev/null +++ b/42sh/libft/src/mem/ft_memchr.c @@ -0,0 +1,29 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_memchr.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/03 14:57:28 by jhalford #+# #+# */ +/* Updated: 2016/11/11 17:41:21 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void *ft_memchr(const void *s, int c, size_t n) +{ + void *a; + size_t i; + + i = -1; + a = (unsigned char *)s; + while (++i < n) + { + if (*(unsigned char *)a == (unsigned char)c) + return (a); + a++; + } + return (NULL); +} diff --git a/42sh/libft/src/mem/ft_memcmp.c b/42sh/libft/src/mem/ft_memcmp.c new file mode 100644 index 00000000..9dd827ee --- /dev/null +++ b/42sh/libft/src/mem/ft_memcmp.c @@ -0,0 +1,28 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_memcmp.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/03 14:57:30 by jhalford #+# #+# */ +/* Updated: 2016/11/03 15:44:21 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +int ft_memcmp(const void *s1, const void *s2, size_t n) +{ + size_t i; + int cmp; + + i = -1; + while (++i < n) + { + cmp = *(unsigned char *)s1++ - *(unsigned char *)s2++; + if (cmp) + return (cmp); + } + return (cmp); +} diff --git a/42sh/libft/src/mem/ft_memcpy.c b/42sh/libft/src/mem/ft_memcpy.c new file mode 100644 index 00000000..a8edafaa --- /dev/null +++ b/42sh/libft/src/mem/ft_memcpy.c @@ -0,0 +1,28 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_memcpy.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/03 14:57:31 by jhalford #+# #+# */ +/* Updated: 2017/03/06 15:39:36 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void *ft_memcpy(void *dst, const void *src, size_t n) +{ + char *c1; + char *c2; + + if (n == 0 || dst == src) + return (dst); + c1 = (char *)dst; + c2 = (char *)src; + while (--n) + *c1++ = *c2++; + *c1 = *c2; + return (dst); +} diff --git a/42sh/libft/src/mem/ft_memdel.c b/42sh/libft/src/mem/ft_memdel.c new file mode 100644 index 00000000..59a18066 --- /dev/null +++ b/42sh/libft/src/mem/ft_memdel.c @@ -0,0 +1,22 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_memdel.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/03 14:57:33 by jhalford #+# #+# */ +/* Updated: 2017/03/20 16:19:07 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void ft_memdel(void **ap) +{ + if (ap && *ap) + { + free(*ap); + *ap = NULL; + } +} diff --git a/42sh/libft/src/mem/ft_memmove.c b/42sh/libft/src/mem/ft_memmove.c new file mode 100644 index 00000000..904d1aca --- /dev/null +++ b/42sh/libft/src/mem/ft_memmove.c @@ -0,0 +1,31 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_memmove.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/03 14:57:34 by jhalford #+# #+# */ +/* Updated: 2016/11/11 17:41:14 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void *ft_memmove(void *dst, const void *src, size_t len) +{ + char *srcc; + char *dstc; + size_t i; + + i = -1; + srcc = (char *)src; + dstc = (char *)dst; + if (srcc < dstc) + while ((int)(--len) >= 0) + *(dstc + len) = *(srcc + len); + else + while (++i < len) + *(dstc + i) = *(srcc + i); + return (dst); +} diff --git a/42sh/libft/src/mem/ft_memset.c b/42sh/libft/src/mem/ft_memset.c new file mode 100644 index 00000000..b99906e2 --- /dev/null +++ b/42sh/libft/src/mem/ft_memset.c @@ -0,0 +1,23 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_memset.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/03 14:57:36 by jhalford #+# #+# */ +/* Updated: 2017/03/06 15:39:24 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void *ft_memset(void *b, int c, size_t len) +{ + size_t i; + + i = -1; + while (++i < len) + ((unsigned char *)b)[i] = (unsigned char)c; + return (b); +} diff --git a/42sh/libft/src/mem/ft_realloc.c b/42sh/libft/src/mem/ft_realloc.c new file mode 100644 index 00000000..33f667a8 --- /dev/null +++ b/42sh/libft/src/mem/ft_realloc.c @@ -0,0 +1,23 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_realloc.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/11 17:37:53 by jhalford #+# #+# */ +/* Updated: 2017/03/21 15:43:51 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void *ft_realloc(void *data, int size) +{ + void *new; + + new = ft_memalloc(size); + ft_memcpy(new, data, ft_strlen(data)); + ft_memdel(&data); + return (new); +} diff --git a/42sh/libft/src/path/ft_path_notdir.c b/42sh/libft/src/path/ft_path_notdir.c new file mode 100644 index 00000000..b59044f3 --- /dev/null +++ b/42sh/libft/src/path/ft_path_notdir.c @@ -0,0 +1,24 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_path_notdir.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/04 11:45:07 by jhalford #+# #+# */ +/* Updated: 2017/03/25 15:03:39 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +char *ft_path_notdir(char *path) +{ + char *slash; + char *ret; + + ret = path; + if ((slash = ft_strrchr(path, '/')) && slash != path) + ret = slash + 1; + return (ret); +} diff --git a/42sh/libft/src/printing/ft_putchar.c b/42sh/libft/src/printing/ft_putchar.c new file mode 100644 index 00000000..400ebaaa --- /dev/null +++ b/42sh/libft/src/printing/ft_putchar.c @@ -0,0 +1,25 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_putchar.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/03 14:57:37 by jhalford #+# #+# */ +/* Updated: 2016/11/04 13:11:49 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +int ft_putchar_fd(int c, int fd) +{ + write(fd, &c, 1); + return (0); +} + +int ft_putchar(int c) +{ + write(1, &c, 1); + return (0); +} diff --git a/42sh/libft/src/printing/ft_putendl.c b/42sh/libft/src/printing/ft_putendl.c new file mode 100644 index 00000000..f54881d8 --- /dev/null +++ b/42sh/libft/src/printing/ft_putendl.c @@ -0,0 +1,27 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_putendl.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/03 14:57:40 by jhalford #+# #+# */ +/* Updated: 2017/02/20 18:17:01 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void ft_putendl_fd(char const *s, int fd) +{ + char nl; + + nl = '\n'; + write(fd, s, ft_strlen(s)); + write(fd, &nl, 1); +} + +void ft_putendl(char const *s) +{ + ft_putendl_fd(s, 1); +} diff --git a/42sh/libft/src/printing/ft_putnbr.c b/42sh/libft/src/printing/ft_putnbr.c new file mode 100644 index 00000000..6d46a4de --- /dev/null +++ b/42sh/libft/src/printing/ft_putnbr.c @@ -0,0 +1,44 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_putnbr.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/08/02 21:25:03 by jhalford #+# #+# */ +/* Updated: 2017/02/18 17:47:04 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void ft_putnbr_loop(long n, int base, int fd) +{ + if (n >= base) + ft_putnbr_loop(n / base, base, fd); + ft_putchar_fd("0123456789abcdef"[n % base], fd); +} + +void ft_putnbr_hex_fd(long n, int fd) +{ + ft_putstr_fd("0x", fd); + ft_putnbr_loop(n, 16, fd); +} + +void ft_putnbr_fd(long n, int fd) +{ + if (n < 0) + ft_putchar_fd('-', fd); + n = FT_ABS(n); + ft_putnbr_loop(n, 10, fd); +} + +void ft_putnbr_hex(long n) +{ + ft_putnbr_hex_fd(n, 1); +} + +void ft_putnbr(long n) +{ + ft_putnbr_fd(n, 1); +} diff --git a/42sh/libft/src/printing/ft_putstr.c b/42sh/libft/src/printing/ft_putstr.c new file mode 100644 index 00000000..d937668e --- /dev/null +++ b/42sh/libft/src/printing/ft_putstr.c @@ -0,0 +1,23 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_putstr.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/08/03 16:13:07 by jhalford #+# #+# */ +/* Updated: 2016/08/25 17:03:59 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void ft_putstr_fd(char const *s, int fd) +{ + write(fd, s, ft_strlen(s)); +} + +void ft_putstr(char const *s) +{ + write(1, s, ft_strlen(s)); +} diff --git a/42sh/libft/src/sstr/ft_sstradd.c b/42sh/libft/src/sstr/ft_sstradd.c new file mode 100644 index 00000000..c81a256d --- /dev/null +++ b/42sh/libft/src/sstr/ft_sstradd.c @@ -0,0 +1,32 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_sstradd.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/03 18:03:58 by jhalford #+# #+# */ +/* Updated: 2017/03/21 15:43:51 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +char **ft_sstradd(char **sstr, char *new) +{ + int size; + char **newlist; + + size = 0; + if (sstr) + while (sstr[size]) + size++; + if (!(newlist = (char **)ft_memalloc(sizeof(char *) * (size + 2)))) + return (NULL); + if (sstr) + ft_memcpy(newlist, sstr, sizeof(char*) * size); + newlist[size] = ft_strdup(new); + newlist[size + 1] = NULL; + free(sstr); + return (newlist); +} diff --git a/42sh/libft/src/sstr/ft_sstrcat.c b/42sh/libft/src/sstr/ft_sstrcat.c new file mode 100644 index 00000000..313fc24d --- /dev/null +++ b/42sh/libft/src/sstr/ft_sstrcat.c @@ -0,0 +1,37 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_sstrcat.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/10 16:58:06 by jhalford #+# #+# */ +/* Updated: 2016/12/10 17:03:27 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +char *ft_sstrcat(char **sstr, char sep) +{ + int len; + int i; + char *out; + + i = 0; + len = 0; + if (!sstr) + return (NULL); + while (sstr[i]) + len += ft_strlen(sstr[i++]); + if (!(out = ft_strnew(sizeof(char) * (len + i + 1)))) + return (NULL); + ft_strcpy(out, sstr[0]); + i = 1; + while (sstr[i]) + { + ft_strcat(out, (char[]){sep, 0}); + ft_strcat(out, sstr[i++]); + } + return (out); +} diff --git a/42sh/libft/src/sstr/ft_sstrdel.c b/42sh/libft/src/sstr/ft_sstrdel.c new file mode 100644 index 00000000..403fcf00 --- /dev/null +++ b/42sh/libft/src/sstr/ft_sstrdel.c @@ -0,0 +1,26 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_sstrdel.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/03 18:04:07 by jhalford #+# #+# */ +/* Updated: 2017/03/25 01:38:51 by wescande ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void ft_sstrdel(char **sstr, int index) +{ + int i; + + i = index; + ft_strdel(&sstr[index]); + while (i == index || sstr[i]) + { + sstr[i] = sstr[i + 1]; + ++i; + } +} diff --git a/42sh/libft/src/sstr/ft_sstrdup.c b/42sh/libft/src/sstr/ft_sstrdup.c new file mode 100644 index 00000000..8517a125 --- /dev/null +++ b/42sh/libft/src/sstr/ft_sstrdup.c @@ -0,0 +1,33 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_sstrdup.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/07 14:25:45 by jhalford #+# #+# */ +/* Updated: 2017/03/21 15:42:19 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +char **ft_sstrdup(char **list) +{ + int i; + int size; + char **cpy; + + i = 0; + size = 0; + while (list[size]) + size++; + cpy = (char **)ft_malloc(sizeof(char *) * (size + 1)); + while (*list) + { + cpy[i++] = ft_strdup(*list); + list++; + } + cpy[i] = NULL; + return (cpy); +} diff --git a/42sh/libft/src/sstr/ft_sstrfree.c b/42sh/libft/src/sstr/ft_sstrfree.c new file mode 100644 index 00000000..7855228d --- /dev/null +++ b/42sh/libft/src/sstr/ft_sstrfree.c @@ -0,0 +1,30 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_sstrfree.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/05 11:53:36 by jhalford #+# #+# */ +/* Updated: 2017/03/22 23:19:24 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void ft_sstrfree(char **sstr) +{ + int i; + + i = 0; + if (sstr) + { + while (sstr[i]) + { + ft_strdel(sstr + i); + i++; + } + ft_strdel(sstr + i); + free(sstr); + } +} diff --git a/42sh/libft/src/sstr/ft_sstrmerge.c b/42sh/libft/src/sstr/ft_sstrmerge.c new file mode 100644 index 00000000..2705a285 --- /dev/null +++ b/42sh/libft/src/sstr/ft_sstrmerge.c @@ -0,0 +1,28 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_sstrmerge.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/24 17:40:50 by jhalford #+# #+# */ +/* Updated: 2017/03/24 18:05:08 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +char **ft_sstrmerge(char **s1, char **s2) +{ + char **out; + + out = ft_sstrdup(s1); + if (!s2) + return (out); + while (*s2) + { + out = ft_sstradd(out, *s2); + s2++; + } + return (out); +} diff --git a/42sh/libft/src/sstr/ft_sstrprint.c b/42sh/libft/src/sstr/ft_sstrprint.c new file mode 100644 index 00000000..1ebc0f5e --- /dev/null +++ b/42sh/libft/src/sstr/ft_sstrprint.c @@ -0,0 +1,18 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_sstrprint.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/28 15:17:33 by jhalford #+# #+# */ +/* Updated: 2016/11/28 15:18:12 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void ft_sstrprint(char **list, char sep) +{ + ft_sstrprint_fd(STDOUT, list, sep); +} diff --git a/42sh/libft/src/sstr/ft_sstrprint_fd.c b/42sh/libft/src/sstr/ft_sstrprint_fd.c new file mode 100644 index 00000000..42225b7c --- /dev/null +++ b/42sh/libft/src/sstr/ft_sstrprint_fd.c @@ -0,0 +1,28 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_sstrprint_fd.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/28 15:17:29 by jhalford #+# #+# */ +/* Updated: 2017/03/18 03:37:16 by wescande ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void ft_sstrprint_fd(int fd, char **list, char sep) +{ + int i; + + i = 0; + if (!list || !*list) + return ; + while (list[i]) + { + ft_putstr_fd(list[i++], fd); + if (list[i]) + ft_putchar_fd(sep, fd); + } +} diff --git a/42sh/libft/src/sstr/ft_sstrsort.c b/42sh/libft/src/sstr/ft_sstrsort.c new file mode 100644 index 00000000..25cf4134 --- /dev/null +++ b/42sh/libft/src/sstr/ft_sstrsort.c @@ -0,0 +1,33 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_sstrsort.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/03 18:03:37 by jhalford #+# #+# */ +/* Updated: 2017/03/23 14:40:25 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void ft_sstrsort(char **list, int (*cmp)()) +{ + int i; + char *tmp; + + i = 0; + while (list[i] && list[i + 1]) + { + if ((*cmp)(list[i], list[i + 1]) > 0) + { + tmp = list[i]; + list[i] = list[i + 1]; + list[i + 1] = tmp; + i = 0; + } + else + i++; + } +} diff --git a/42sh/libft/src/sstr/ft_sstrstr.c b/42sh/libft/src/sstr/ft_sstrstr.c new file mode 100644 index 00000000..d6618563 --- /dev/null +++ b/42sh/libft/src/sstr/ft_sstrstr.c @@ -0,0 +1,29 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_sstrstr.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ariard +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/07 11:29:54 by ariard #+# #+# */ +/* Updated: 2017/03/22 21:54:40 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +char *ft_sstrstr(char **sstr, char *find) +{ + int size; + + if (!sstr) + return (NULL); + size = ft_strlen(find); + while ((*sstr)) + { + if (ft_strncmp(*sstr, find, size) == 0) + return (*sstr); + sstr++; + } + return (NULL); +} diff --git a/42sh/libft/src/str/ft_atoi.c b/42sh/libft/src/str/ft_atoi.c new file mode 100644 index 00000000..546c58f6 --- /dev/null +++ b/42sh/libft/src/str/ft_atoi.c @@ -0,0 +1,51 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_atoi.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/08/03 16:17:21 by jhalford #+# #+# */ +/* Updated: 2017/03/22 22:21:21 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +static int ft_iswhitespace(char c) +{ + if (c == ' ' || c == '\t' || c == '\n') + return (1); + else if (c == '\v' || c == '\f' || c == '\r') + return (1); + return (0); +} + +int ft_atoi(const char *str) +{ + int i; + int res; + int sign; + + if (!str || !*str) + return (0); + i = 0; + res = 0; + sign = 1; + while (ft_iswhitespace(str[i])) + i++; + if (str[i] == '-' || str[i] == '+') + { + if (str[i + 1] >= '0' && str[i + 1] <= '9') + { + sign = (str[i] == '+') ? 1 : -1; + i++; + } + else + return (0); + } + while (str[i] >= '0' && str[i] <= '9') + res = res * 10 + str[i++] - '0'; + res *= sign; + return (res); +} diff --git a/42sh/libft/src/str/ft_convert_base.c b/42sh/libft/src/str/ft_convert_base.c new file mode 100644 index 00000000..633a82ef --- /dev/null +++ b/42sh/libft/src/str/ft_convert_base.c @@ -0,0 +1,86 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_convert_base.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/08/07 23:31:20 by jhalford #+# #+# */ +/* Updated: 2016/11/03 18:03:07 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +static int get_size(char *str) +{ + int i; + int j; + + i = 0; + while (str[i] != '\0') + { + if (str[i] == '+' || str[i] == '-') + return (0); + if (str[i] < 32 || str[i] > 126) + return (0); + j = 0; + while (j < i) + { + if (str[j] == str[i]) + return (0); + j++; + } + i++; + } + return (i); +} + +static int get_pos(char c, char *str) +{ + int i; + + i = 0; + while (c != str[i] && str[i]) + i++; + return (i); +} + +static int ft_check_str(char *str, char *base, int base_size) +{ + while (*str) + { + if (!(get_pos(*str, base) < base_size || *str == '-' || *str == '+')) + return (0); + str++; + } + return (1); +} + +char *ft_convert_base( + char *str, char *base_from, char *base_to, char *flags) +{ + int base_size; + int res; + int sign; + + base_size = get_size(base_from); + res = 0; + sign = 1; + if (!ft_check_str(str, base_from, base_size)) + return (ft_itoa_base(0, "0", flags)); + if (base_size > 1) + { + if (*str == '-' || *str == '+') + { + if (get_pos(*(str + 1), base_from) < base_size) + sign = (*str == '+') ? 1 : -1; + else + return (ft_itoa_base(0, "0", flags)); + str++; + } + while (get_pos(*str, base_from) < base_size) + res = res * base_size + sign * get_pos(*str++, base_from); + } + return (ft_itoa_base(res, base_to, flags)); +} diff --git a/42sh/libft/src/str/ft_putaddr_fd.c b/42sh/libft/src/str/ft_putaddr_fd.c new file mode 100644 index 00000000..a6c52a37 --- /dev/null +++ b/42sh/libft/src/str/ft_putaddr_fd.c @@ -0,0 +1,36 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_putaddr_fd.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/18 18:47:04 by jhalford #+# #+# */ +/* Updated: 2017/02/18 18:48:58 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void ft_putaddr_fd(void *a, int fd) +{ + char out[19]; + unsigned long long addr; + int i; + + ft_putnbr((long)a); + ft_putchar('\n'); + addr = (unsigned long long)a; + out[18] = 0; + i = 17; + while (addr) + { + ft_putnbr(addr); + ft_putchar('\n'); + out[i--] = "0123456789ABCDEF"[addr % 16]; + addr /= 16; + } + out[i--] = 'x'; + out[i] = '0'; + ft_putstr_fd(out + i, fd); +} diff --git a/42sh/libft/src/str/ft_split_whitespaces.c b/42sh/libft/src/str/ft_split_whitespaces.c new file mode 100644 index 00000000..ed744d0d --- /dev/null +++ b/42sh/libft/src/str/ft_split_whitespaces.c @@ -0,0 +1,79 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_split_whitespaces.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/03 16:07:17 by jhalford #+# #+# */ +/* Updated: 2017/03/21 15:42:19 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +char *ft_strdupi_w(char const *s) +{ + int i; + char *str; + + i = 0; + while (s[i] && s[i] != ' ' && s[i] != '\t') + i++; + str = (char *)ft_malloc(sizeof(char) * (i + 1)); + if (str) + { + str[i--] = '\0'; + while (i >= 0) + { + str[i] = s[i]; + i--; + } + } + return (str); +} + +static int ft_len_words(char const *s) +{ + int i; + int len; + + i = 0; + len = 0; + while (s[i]) + { + if ((i == 0 && s[i] != ' ' && s[i] != '\t') || ((s[i] != ' ' + && s[i] != '\t') && (s[i - 1] == ' ' || s[i - 1] == '\t'))) + len++; + i++; + } + return (len); +} + +char **ft_split_whitespaces(char const *s) +{ + int i; + char **str; + int j; + + str = NULL; + if (!(s)) + return (str); + str = (char **)ft_malloc(sizeof(char *) * (ft_len_words(s) + 1)); + i = 0; + j = 0; + if (!(str)) + return (str); + while (s[i]) + { + if ((i == 0 && s[i] != ' ' && s[i] != '\t') || ((s[i] != ' ' + && s[i] != '\t') && (s[i - 1] == ' ' || s[i - 1] == '\t'))) + { + str[j] = ft_strdupi_w((s + i)); + j++; + } + i++; + } + str[j] = NULL; + return (str); +} diff --git a/42sh/libft/src/str/ft_str3join.c b/42sh/libft/src/str/ft_str3join.c new file mode 100644 index 00000000..91384cbc --- /dev/null +++ b/42sh/libft/src/str/ft_str3join.c @@ -0,0 +1,26 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_str3join.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/03 18:03:26 by jhalford #+# #+# */ +/* Updated: 2017/03/13 16:07:24 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +char *ft_str3join(char const *s1, char const *s2, char const *s3) +{ + char *join; + int size; + + size = ft_strlen(s1) + ft_strlen(s2) + ft_strlen(s3); + join = ft_strnew(size + 1); + ft_strcpy(join, s1); + ft_strcat(join, s2); + ft_strcat(join, s3); + return (join); +} diff --git a/42sh/libft/src/str/ft_strappend.c b/42sh/libft/src/str/ft_strappend.c new file mode 100644 index 00000000..2e52529d --- /dev/null +++ b/42sh/libft/src/str/ft_strappend.c @@ -0,0 +1,24 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strappend.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/13 12:16:31 by jhalford #+# #+# */ +/* Updated: 2017/02/19 05:50:12 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +int ft_strappend(char **dst, char *src) +{ + char *out; + + if (!(out = ft_strjoin(*dst, src))) + return (-1); + ft_strdel(dst); + *dst = out; + return (0); +} diff --git a/42sh/libft/src/str/ft_strbetween.c b/42sh/libft/src/str/ft_strbetween.c new file mode 100644 index 00000000..7492077e --- /dev/null +++ b/42sh/libft/src/str/ft_strbetween.c @@ -0,0 +1,22 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strbetween.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/11 16:26:44 by jhalford #+# #+# */ +/* Updated: 2017/01/12 14:54:17 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +char *ft_strbetween(char *start, char *end) +{ + char *out; + + out = ft_strnew(end - start + 1); + ft_strncpy(out, start, end - start); + return (out); +} diff --git a/42sh/libft/src/str/ft_strcat.c b/42sh/libft/src/str/ft_strcat.c new file mode 100644 index 00000000..76f6f25c --- /dev/null +++ b/42sh/libft/src/str/ft_strcat.c @@ -0,0 +1,26 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strcat.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/08/07 10:56:53 by jhalford #+# #+# */ +/* Updated: 2017/03/21 14:21:22 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +char *ft_strcat(char *s1, const char *s2) +{ + char *start; + + start = s1; + s1 += ft_strlen(s1); + if (s2) + while (*s2) + *s1++ = *s2++; + *s1 = 0; + return (start); +} diff --git a/42sh/libft/src/str/ft_strcatf.c b/42sh/libft/src/str/ft_strcatf.c new file mode 100644 index 00000000..8caa7036 --- /dev/null +++ b/42sh/libft/src/str/ft_strcatf.c @@ -0,0 +1,23 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strcatf.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/07 15:46:03 by jhalford #+# #+# */ +/* Updated: 2016/12/09 19:02:20 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +char *ft_strcatf(char *s1, const char *s2) +{ + char buf[ft_strlen(s1) + 1]; + + ft_strcpy(buf, s1); + ft_strcpy(s1, s2); + ft_strcat(s1, buf); + return (s1); +} diff --git a/42sh/libft/src/str/ft_strchr.c b/42sh/libft/src/str/ft_strchr.c new file mode 100644 index 00000000..c2ad43f6 --- /dev/null +++ b/42sh/libft/src/str/ft_strchr.c @@ -0,0 +1,31 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strchr.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/03 14:57:53 by jhalford #+# #+# */ +/* Updated: 2017/02/20 16:43:10 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +char *ft_strchr(const char *s, int c) +{ + char *a; + + if (!s) + return (NULL); + a = (char *)s; + while (*a) + { + if (*a == (char)c) + return (a); + a++; + } + if (*a == (char)c) + return (a); + return (NULL); +} diff --git a/42sh/libft/src/str/ft_strchrcpy.c b/42sh/libft/src/str/ft_strchrcpy.c new file mode 100644 index 00000000..06b88879 --- /dev/null +++ b/42sh/libft/src/str/ft_strchrcpy.c @@ -0,0 +1,21 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strchrcpy.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ariard +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/01 15:43:59 by ariard #+# #+# */ +/* Updated: 2017/03/07 11:08:55 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +char *ft_strchrcpy(char *dst, const char *src, char c) +{ + while (*src && *src != c) + *dst++ = *src++; + *dst = '\0'; + return (dst); +} diff --git a/42sh/libft/src/str/ft_strclr.c b/42sh/libft/src/str/ft_strclr.c new file mode 100644 index 00000000..834eb6f1 --- /dev/null +++ b/42sh/libft/src/str/ft_strclr.c @@ -0,0 +1,24 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strclr.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/03 14:57:54 by jhalford #+# #+# */ +/* Updated: 2016/11/03 14:57:55 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void ft_strclr(char *s) +{ + size_t size; + size_t i; + + size = ft_strlen(s); + i = -1; + while (++i < size) + s[i] = 0; +} diff --git a/42sh/libft/src/str/ft_strcmp.c b/42sh/libft/src/str/ft_strcmp.c new file mode 100644 index 00000000..de85d971 --- /dev/null +++ b/42sh/libft/src/str/ft_strcmp.c @@ -0,0 +1,25 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strcmp.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/08/07 10:49:02 by jhalford #+# #+# */ +/* Updated: 2017/03/14 18:09:26 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +int ft_strcmp(const char *s1, const char *s2) +{ + int i; + + i = 0; + if (!s1 || !s2) + return (1); + while (*(s1 + i) && *(s1 + i) == *(s2 + i)) + i++; + return (*((unsigned char*)s1 + i) - *((unsigned char*)s2 + i)); +} diff --git a/42sh/libft/src/str/ft_strcpy.c b/42sh/libft/src/str/ft_strcpy.c new file mode 100644 index 00000000..63ee8897 --- /dev/null +++ b/42sh/libft/src/str/ft_strcpy.c @@ -0,0 +1,27 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strcpy.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/08/07 10:48:12 by jhalford #+# #+# */ +/* Updated: 2017/03/13 16:06:49 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +char *ft_strcpy(char *dst, const char *src) +{ + int i; + + i = 0; + while (src && src[i]) + { + dst[i] = src[i]; + i++; + } + dst[i] = '\0'; + return (dst); +} diff --git a/42sh/libft/src/str/ft_strcspn.c b/42sh/libft/src/str/ft_strcspn.c new file mode 100644 index 00000000..d55d8081 --- /dev/null +++ b/42sh/libft/src/str/ft_strcspn.c @@ -0,0 +1,26 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strcspn.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/20 15:55:33 by jhalford #+# #+# */ +/* Updated: 2017/03/20 16:00:37 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +size_t ft_strcspn(char *s, const char *delim) +{ + char *str; + + str = s; + while (*str) + if (ft_strchr(delim, *str)) + return (str - s); + else + str++; + return (str - s); +} diff --git a/42sh/libft/src/str/ft_strcut.c b/42sh/libft/src/str/ft_strcut.c new file mode 100644 index 00000000..75b4d51b --- /dev/null +++ b/42sh/libft/src/str/ft_strcut.c @@ -0,0 +1,24 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strcut.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/03 18:04:37 by jhalford #+# #+# */ +/* Updated: 2016/11/03 18:04:37 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +char *ft_strcut(char *str, char *cut) +{ + char *target; + + while ((target = ft_strstr(str, cut))) + { + ft_strcpy(target, target + ft_strlen(cut)); + } + return (str); +} diff --git a/42sh/libft/src/str/ft_strdel.c b/42sh/libft/src/str/ft_strdel.c new file mode 100644 index 00000000..f9eb34e4 --- /dev/null +++ b/42sh/libft/src/str/ft_strdel.c @@ -0,0 +1,22 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strdel.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/03 14:58:00 by jhalford #+# #+# */ +/* Updated: 2017/02/19 05:47:47 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void ft_strdel(char **as) +{ + if (as && *as) + { + free(*as); + *as = NULL; + } +} diff --git a/42sh/libft/src/str/ft_strdup.c b/42sh/libft/src/str/ft_strdup.c new file mode 100644 index 00000000..556558f4 --- /dev/null +++ b/42sh/libft/src/str/ft_strdup.c @@ -0,0 +1,23 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strdup.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/07 14:25:41 by jhalford #+# #+# */ +/* Updated: 2017/03/21 15:42:19 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +char *ft_strdup(const char *s1) +{ + char *dup; + + if (!s1 || !(dup = (char*)ft_malloc(sizeof(*dup) * (ft_strlen(s1) + 1)))) + return (NULL); + ft_strcpy(dup, s1); + return (dup); +} diff --git a/42sh/libft/src/str/ft_strdupchr.c b/42sh/libft/src/str/ft_strdupchr.c new file mode 100644 index 00000000..3fd5d0d5 --- /dev/null +++ b/42sh/libft/src/str/ft_strdupchr.c @@ -0,0 +1,23 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strdupchr.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ariard +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/07 11:01:15 by ariard #+# #+# */ +/* Updated: 2017/03/22 23:12:37 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +char *ft_strdupchr(const char *str, char c) +{ + char *new; + + if (!str || !(new = ft_memalloc(sizeof(*new) * (ft_strlenchr(str, c) + 1)))) + return (NULL); + ft_strchrcpy(new, str, c); + return (new); +} diff --git a/42sh/libft/src/str/ft_strduptr.c b/42sh/libft/src/str/ft_strduptr.c new file mode 100644 index 00000000..59cfd835 --- /dev/null +++ b/42sh/libft/src/str/ft_strduptr.c @@ -0,0 +1,26 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strduptr.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ariard +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/06 13:37:12 by ariard #+# #+# */ +/* Updated: 2017/03/21 15:43:52 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +char *ft_strduptr(char *str, int (*is)(int c)) +{ + char *new; + char *tmp; + + new = ft_memalloc(sizeof(char *) * ft_strlen(str) + 1); + tmp = new; + while (*str && (is)((int)*str)) + *new++ = *str++; + *new = 0; + return (tmp); +} diff --git a/42sh/libft/src/str/ft_strequ.c b/42sh/libft/src/str/ft_strequ.c new file mode 100644 index 00000000..88e5580c --- /dev/null +++ b/42sh/libft/src/str/ft_strequ.c @@ -0,0 +1,18 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strequ.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/03 14:58:04 by jhalford #+# #+# */ +/* Updated: 2016/11/03 15:02:10 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +int ft_strequ(char const *s1, char const *s2) +{ + return (ft_strcmp(s1, s2) == 0); +} diff --git a/42sh/libft/src/str/ft_strinsert.c b/42sh/libft/src/str/ft_strinsert.c new file mode 100644 index 00000000..fcf8b1b6 --- /dev/null +++ b/42sh/libft/src/str/ft_strinsert.c @@ -0,0 +1,24 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strinsert.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/21 18:21:57 by jhalford #+# #+# */ +/* Updated: 2016/11/21 18:21:57 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +char *ft_strinsert(char *str, char c, int n) +{ + char tmp[ft_strlen(str)]; + char *out; + + ft_strcpy(tmp, str + n); + str[n] = 0; + out = ft_str3join(str, (char[]){c, 0}, tmp); + return (out); +} diff --git a/42sh/libft/src/str/ft_stris.c b/42sh/libft/src/str/ft_stris.c new file mode 100644 index 00000000..ba809f85 --- /dev/null +++ b/42sh/libft/src/str/ft_stris.c @@ -0,0 +1,21 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_stris.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ariard +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/02 15:11:28 by ariard #+# #+# */ +/* Updated: 2017/03/20 16:01:06 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +int ft_stris(char *str, int (*f)()) +{ + while (*str) + if (!(f)(*str++)) + return (0); + return (1); +} diff --git a/42sh/libft/src/str/ft_striter.c b/42sh/libft/src/str/ft_striter.c new file mode 100644 index 00000000..8c309549 --- /dev/null +++ b/42sh/libft/src/str/ft_striter.c @@ -0,0 +1,24 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_striter.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/03 14:58:13 by jhalford #+# #+# */ +/* Updated: 2016/11/03 14:58:13 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void ft_striter(char *s, void (*f)(char *)) +{ + size_t size; + size_t i; + + size = ft_strlen(s); + i = -1; + while (++i < size) + (*f)(s + i); +} diff --git a/42sh/libft/src/str/ft_striteri.c b/42sh/libft/src/str/ft_striteri.c new file mode 100644 index 00000000..80cdd8b5 --- /dev/null +++ b/42sh/libft/src/str/ft_striteri.c @@ -0,0 +1,24 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_striteri.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/03 14:58:15 by jhalford #+# #+# */ +/* Updated: 2016/11/03 14:58:15 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void ft_striteri(char *s, void (*f)(unsigned int, char *)) +{ + size_t size; + size_t i; + + size = ft_strlen(s); + i = -1; + while (++i < size) + (*f)(i, s + i); +} diff --git a/42sh/libft/src/str/ft_strjoin.c b/42sh/libft/src/str/ft_strjoin.c new file mode 100644 index 00000000..2c064f33 --- /dev/null +++ b/42sh/libft/src/str/ft_strjoin.c @@ -0,0 +1,26 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strjoin.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/03 14:58:18 by jhalford #+# #+# */ +/* Updated: 2017/02/19 05:50:20 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +char *ft_strjoin(char const *s1, char const *s2) +{ + char *join; + + if (!(join = ft_strnew(ft_strlen(s1) + ft_strlen(s2) + 1))) + return (NULL); + if (s1) + ft_strcpy(join, s1); + if (s2) + ft_strcat(join, s2); + return (join); +} diff --git a/42sh/libft/src/str/ft_strlcat.c b/42sh/libft/src/str/ft_strlcat.c new file mode 100644 index 00000000..df94eea4 --- /dev/null +++ b/42sh/libft/src/str/ft_strlcat.c @@ -0,0 +1,31 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strlcat.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/08/07 10:57:16 by jhalford #+# #+# */ +/* Updated: 2016/08/07 21:44:13 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +size_t ft_strlcat(char *dst, const char *src, size_t size) +{ + size_t i; + size_t dst_size; + size_t src_size; + + dst_size = ft_strlen(dst); + src_size = ft_strlen(src); + i = 0; + while (src[i] != '\0' && ((dst_size + i) < (size - 1))) + { + dst[dst_size + i] = src[i]; + i++; + } + dst[dst_size + i] = '\0'; + return (src_size + ((dst_size < size) ? dst_size : size)); +} diff --git a/42sh/libft/src/str/ft_strlen.c b/42sh/libft/src/str/ft_strlen.c new file mode 100644 index 00000000..9b65ad39 --- /dev/null +++ b/42sh/libft/src/str/ft_strlen.c @@ -0,0 +1,25 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strlen.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/03 14:58:22 by jhalford #+# #+# */ +/* Updated: 2017/03/18 14:25:09 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +size_t ft_strlen(const char *s) +{ + int i; + + i = 0; + if (!s) + return (0); + while (s[i]) + i++; + return (i); +} diff --git a/42sh/libft/src/str/ft_strlenchr.c b/42sh/libft/src/str/ft_strlenchr.c new file mode 100644 index 00000000..1ea82cfa --- /dev/null +++ b/42sh/libft/src/str/ft_strlenchr.c @@ -0,0 +1,23 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strlenchr.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ariard +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/01 16:10:54 by ariard #+# #+# */ +/* Updated: 2017/03/22 22:12:03 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +size_t ft_strlenchr(const char *s, char c) +{ + size_t i; + + i = 0; + while (*s && *s++ != c) + i++; + return (i); +} diff --git a/42sh/libft/src/str/ft_strmap.c b/42sh/libft/src/str/ft_strmap.c new file mode 100644 index 00000000..5c0353ae --- /dev/null +++ b/42sh/libft/src/str/ft_strmap.c @@ -0,0 +1,29 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strmap.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/03 14:58:24 by jhalford #+# #+# */ +/* Updated: 2017/03/21 15:42:19 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +char *ft_strmap(char const *s, char (*f)(char)) +{ + size_t size; + size_t i; + char *out; + + size = ft_strlen(s); + out = (char *)ft_malloc(sizeof(char) * (size + 1)); + if (out == NULL) + return (NULL); + i = -1; + while (++i < size) + out[i] = (*f)(s[i]); + return (out); +} diff --git a/42sh/libft/src/str/ft_strmapi.c b/42sh/libft/src/str/ft_strmapi.c new file mode 100644 index 00000000..7cc6d089 --- /dev/null +++ b/42sh/libft/src/str/ft_strmapi.c @@ -0,0 +1,29 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strmapi.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/03 14:58:28 by jhalford #+# #+# */ +/* Updated: 2017/03/21 15:42:19 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +char *ft_strmapi(char const *s, char (*f)(unsigned int, char)) +{ + size_t size; + size_t i; + char *out; + + size = ft_strlen(s); + out = (char *)ft_malloc(sizeof(char) * (size + 1)); + if (out == NULL) + return (NULL); + i = -1; + while (++i < size) + out[i] = (*f)(i, s[i]); + return (out); +} diff --git a/42sh/libft/src/str/ft_strncat.c b/42sh/libft/src/str/ft_strncat.c new file mode 100644 index 00000000..31ab2262 --- /dev/null +++ b/42sh/libft/src/str/ft_strncat.c @@ -0,0 +1,29 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strncat.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/08/07 10:57:07 by jhalford #+# #+# */ +/* Updated: 2016/11/03 15:02:27 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +char *ft_strncat(char *s1, const char *s2, size_t n) +{ + size_t size; + size_t j; + + size = ft_strlen(s1); + j = 0; + while (s2[j] != '\0' && j < n) + { + s1[size + j] = s2[j]; + j++; + } + s1[size + j] = '\0'; + return (s1); +} diff --git a/42sh/libft/src/str/ft_strncmp.c b/42sh/libft/src/str/ft_strncmp.c new file mode 100644 index 00000000..57b55b5f --- /dev/null +++ b/42sh/libft/src/str/ft_strncmp.c @@ -0,0 +1,26 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strncmp.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/08/07 10:49:12 by jhalford #+# #+# */ +/* Updated: 2016/11/03 16:11:00 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +int ft_strncmp(const char *s1, const char *s2, size_t n) +{ + int i; + + i = 0; + while (*(s1 + i) && *(s1 + i) == *(s2 + i) && i < (int)n) + i++; + if (i < (int)n) + return (*((unsigned char*)s1 + i) - *((unsigned char*)s2 + i)); + else + return (0); +} diff --git a/42sh/libft/src/str/ft_strncpy.c b/42sh/libft/src/str/ft_strncpy.c new file mode 100644 index 00000000..85dd41c7 --- /dev/null +++ b/42sh/libft/src/str/ft_strncpy.c @@ -0,0 +1,31 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strncpy.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/08/07 10:48:21 by jhalford #+# #+# */ +/* Updated: 2016/08/07 10:48:25 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +char *ft_strncpy(char *dst, const char *src, size_t len) +{ + size_t i; + + i = 0; + while (src[i] != '\0' && i < len) + { + dst[i] = src[i]; + i++; + } + while (i < len) + { + dst[i] = '\0'; + i++; + } + return (dst); +} diff --git a/42sh/libft/src/str/ft_strnequ.c b/42sh/libft/src/str/ft_strnequ.c new file mode 100644 index 00000000..5dfd6005 --- /dev/null +++ b/42sh/libft/src/str/ft_strnequ.c @@ -0,0 +1,18 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strnequ.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/03 14:58:32 by jhalford #+# #+# */ +/* Updated: 2016/11/03 15:02:36 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +int ft_strnequ(char const *s1, char const *s2, size_t n) +{ + return (ft_strncmp(s1, s2, n) == 0); +} diff --git a/42sh/libft/src/str/ft_strnew.c b/42sh/libft/src/str/ft_strnew.c new file mode 100644 index 00000000..2e2ae1d6 --- /dev/null +++ b/42sh/libft/src/str/ft_strnew.c @@ -0,0 +1,27 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strnew.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/03 14:58:34 by jhalford #+# #+# */ +/* Updated: 2017/03/21 15:42:19 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +char *ft_strnew(size_t size) +{ + char *addr; + size_t i; + + addr = (char *)ft_malloc(size + 1); + if (addr == NULL) + return (NULL); + i = -1; + while (++i <= size) + addr[i] = '\0'; + return (addr); +} diff --git a/42sh/libft/src/str/ft_strnstr.c b/42sh/libft/src/str/ft_strnstr.c new file mode 100644 index 00000000..efa7e54f --- /dev/null +++ b/42sh/libft/src/str/ft_strnstr.c @@ -0,0 +1,34 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strnstr.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/03 14:58:36 by jhalford #+# #+# */ +/* Updated: 2016/11/03 16:34:42 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +char *ft_strnstr(const char *big, const char *little, size_t len) +{ + size_t i; + int j; + + i = -1; + if (!*little) + return ((char *)big); + while (big[++i] && i < len) + { + j = 0; + while (big[i + j] == little[j] && i + j < len) + { + j++; + if (!little[j]) + return ((char *)big + i); + } + } + return (NULL); +} diff --git a/42sh/libft/src/str/ft_strrchr.c b/42sh/libft/src/str/ft_strrchr.c new file mode 100644 index 00000000..e41d4566 --- /dev/null +++ b/42sh/libft/src/str/ft_strrchr.c @@ -0,0 +1,29 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strrchr.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/03 14:58:38 by jhalford #+# #+# */ +/* Updated: 2016/11/03 15:08:33 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +char *ft_strrchr(const char *s, int c) +{ + char *a; + int i; + + a = (char *)s; + i = ft_strlen(a); + while (i >= 0) + { + if (a[i] == (char)c) + return (a + i); + i--; + } + return (NULL); +} diff --git a/42sh/libft/src/str/ft_strreplace.c b/42sh/libft/src/str/ft_strreplace.c new file mode 100644 index 00000000..7fb72527 --- /dev/null +++ b/42sh/libft/src/str/ft_strreplace.c @@ -0,0 +1,26 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strreplace.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/12 13:50:21 by jhalford #+# #+# */ +/* Updated: 2017/01/12 13:59:25 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +char *ft_strreplace(char **str, char *start, char *end, char *new) +{ + char *out; + + out = ft_strnew(ft_strlen(*str) - (end - start) + ft_strlen(new) + 1); + ft_strncpy(out, *str, start - *str); + ft_strcat(out, new); + ft_strcat(out, end + 1); + ft_strdel(str); + *str = out; + return (out); +} diff --git a/42sh/libft/src/str/ft_strrev.c b/42sh/libft/src/str/ft_strrev.c new file mode 100644 index 00000000..73884204 --- /dev/null +++ b/42sh/libft/src/str/ft_strrev.c @@ -0,0 +1,33 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strrev.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/03 18:01:36 by jhalford #+# #+# */ +/* Updated: 2016/11/03 18:01:36 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +char *ft_strrev(char *str) +{ + int len; + char tmp; + int i; + + i = 0; + len = 0; + while (str[len] != '\0') + len++; + while (i < len / 2) + { + tmp = str[len - (i + 1)]; + str[len - (i + 1)] = str[i]; + str[i] = tmp; + i++; + } + return (str); +} diff --git a/42sh/libft/src/str/ft_strsplit.c b/42sh/libft/src/str/ft_strsplit.c new file mode 100644 index 00000000..049aa7ed --- /dev/null +++ b/42sh/libft/src/str/ft_strsplit.c @@ -0,0 +1,70 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strsplit.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/03 14:58:40 by jhalford #+# #+# */ +/* Updated: 2017/03/21 15:42:19 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +static int ft_countwords(char const *s, char c) +{ + if (c == '\0') + return ((*s == '\0') ? 0 : 1); + while (*s == c) + s++; + if (*s == '\0') + return (0); + while (*s != c && *s != '\0') + s++; + return (1 + ft_countwords(s, c)); +} + +static int get_word_len(char const *str, char c) +{ + int i; + int len; + + i = 0; + len = 0; + while (str[i] == c) + i++; + while (str[i] != c && str[i] != '\0') + { + i++; + len++; + } + return (len); +} + +char **ft_strsplit(char const *s, char c) +{ + int i; + int j; + int k; + char **str2; + + if (!s || !(str2 = (char **)ft_malloc(sizeof(*str2) * + (ft_countwords(s, c) + 1)))) + return (NULL); + i = -1; + j = 0; + while (++i < ft_countwords(s, c)) + { + k = 0; + if (!(str2[i] = ft_strnew(get_word_len(&s[j], c) + 1))) + str2[i] = NULL; + while (s[j] == c) + j++; + while (s[j] != c && s[j]) + str2[i][k++] = s[j++]; + str2[i][k] = '\0'; + } + str2[i] = 0; + return (str2); +} diff --git a/42sh/libft/src/str/ft_strstr.c b/42sh/libft/src/str/ft_strstr.c new file mode 100644 index 00000000..bf8ab37a --- /dev/null +++ b/42sh/libft/src/str/ft_strstr.c @@ -0,0 +1,37 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strstr.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/08/07 10:48:35 by jhalford #+# #+# */ +/* Updated: 2016/11/03 16:28:05 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +char *ft_strstr(const char *big, const char *little) +{ + int i; + int j; + char *a; + + a = (char *)big; + i = 0; + if (!*little) + return (a); + while (a[i]) + { + j = 0; + while (a[i + j] == little[j]) + { + j++; + if (!little[j]) + return (a + i); + } + i++; + } + return (NULL); +} diff --git a/42sh/libft/src/str/ft_strsub.c b/42sh/libft/src/str/ft_strsub.c new file mode 100644 index 00000000..0c3fb11b --- /dev/null +++ b/42sh/libft/src/str/ft_strsub.c @@ -0,0 +1,27 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strsub.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/03 14:58:43 by jhalford #+# #+# */ +/* Updated: 2017/03/21 15:42:19 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +char *ft_strsub(char const *s, unsigned int start, size_t len) +{ + char *out; + size_t i; + + if (!(out = (char *)ft_malloc(sizeof(char) * (len + 1)))) + return (NULL); + i = -1; + while (++i < len) + out[i] = s[i + start]; + out[i] = '\0'; + return (out); +} diff --git a/42sh/libft/src/str/ft_strtok.c b/42sh/libft/src/str/ft_strtok.c new file mode 100644 index 00000000..f051737d --- /dev/null +++ b/42sh/libft/src/str/ft_strtok.c @@ -0,0 +1,36 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strtok.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/07 18:08:31 by jhalford #+# #+# */ +/* Updated: 2017/03/29 14:48:09 by wescande ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +char *ft_strtok(char *s, const char *delim) +{ + static char *lasts = NULL; + int ch; + + if (!s) + { + if (!lasts) + return (NULL); + s = lasts; + } + if ((ch = *s++) == 0) + return (0); + while (ft_strchr(delim, ch)) + if ((ch = *s++) == 0) + return (0); + --s; + lasts = s + ft_strcspn(s, delim); + if (*lasts != 0) + *lasts++ = 0; + return (s); +} diff --git a/42sh/libft/src/str/ft_strtrim.c b/42sh/libft/src/str/ft_strtrim.c new file mode 100644 index 00000000..22d17250 --- /dev/null +++ b/42sh/libft/src/str/ft_strtrim.c @@ -0,0 +1,27 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strtrim.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/03 14:58:45 by jhalford #+# #+# */ +/* Updated: 2016/11/04 13:11:59 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +char *ft_strtrim(char const *s) +{ + char *out; + char *last; + + while (*s && FT_WS(*s)) + s++; + out = ft_strdup(s); + last = out + ft_strlen(out) - 1; + while (last > out && FT_WS(*last)) + *last-- = 0; + return (out); +} diff --git a/42sh/libft/src/sys/create_directory.c b/42sh/libft/src/sys/create_directory.c new file mode 100644 index 00000000..3cbeddb0 --- /dev/null +++ b/42sh/libft/src/sys/create_directory.c @@ -0,0 +1,39 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* create_directory.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ariard +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/25 03:18:18 by ariard #+# #+# */ +/* Updated: 2017/03/25 20:24:44 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +char *create_directory(const char *path, const char *old_pathnames) +{ + char *new_pathnames; + char *newdir; + char *temp; + char *semi; + + if (!path || !old_pathnames) + return (NULL); + new_pathnames = ft_strdup(old_pathnames); + temp = new_pathnames; + while (new_pathnames) + { + if ((semi = ft_strchr(new_pathnames, ':'))) + *semi = 0; + if (!is_directory(newdir = ft_str3join(new_pathnames, "/", path))) + ft_strdel(&newdir); + else + break ; + new_pathnames += ft_strlen(new_pathnames) + 1; + } + ft_strdel(&temp); + DG("newdir %s", newdir); + return (newdir); +} diff --git a/42sh/libft/src/sys/dup2_close.c b/42sh/libft/src/sys/dup2_close.c new file mode 100644 index 00000000..c1c10bcd --- /dev/null +++ b/42sh/libft/src/sys/dup2_close.c @@ -0,0 +1,22 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* dup2_close.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/07 16:07:28 by jhalford #+# #+# */ +/* Updated: 2017/03/24 19:33:48 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +int dup2_close(int fd1, int fd2) +{ + if (dup2(fd1, fd2) < 0) + return (-1); + if (close(fd1) < 0) + return (-1); + return (0); +} diff --git a/42sh/libft/src/sys/fd_replace.c b/42sh/libft/src/sys/fd_replace.c new file mode 100644 index 00000000..a3502c52 --- /dev/null +++ b/42sh/libft/src/sys/fd_replace.c @@ -0,0 +1,20 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* fd_replace.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/21 16:32:26 by jhalford #+# #+# */ +/* Updated: 2017/03/27 00:18:52 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +int fd_replace(int fd1, int fd2) +{ + if (fd1 != fd2) + return (dup2_close(fd1, fd2)); + return (-1); +} diff --git a/42sh/libft/src/sys/ft_getenv.c b/42sh/libft/src/sys/ft_getenv.c new file mode 100644 index 00000000..83cebdaa --- /dev/null +++ b/42sh/libft/src/sys/ft_getenv.c @@ -0,0 +1,27 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_getenv.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/01 12:15:45 by jhalford #+# #+# */ +/* Updated: 2017/03/18 03:09:57 by wescande ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +char *ft_getenv(char **env, char *key) +{ + if (!env) + return (NULL); + while (*env) + { + if (ft_strcmp(*env, key) == '=' + && ft_strlen(key) == ft_strlenchr(*env, '=')) + return (*env + ft_strlen(key) + 1); + env++; + } + return (NULL); +} diff --git a/42sh/libft/src/sys/ft_xattr_count.c b/42sh/libft/src/sys/ft_xattr_count.c new file mode 100644 index 00000000..62b274f7 --- /dev/null +++ b/42sh/libft/src/sys/ft_xattr_count.c @@ -0,0 +1,61 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_xattr_count.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/03 18:00:52 by jhalford #+# #+# */ +/* Updated: 2017/03/05 16:48:29 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +#if defined __APPLE__ + +int ft_xattr_count(char *path) +{ + ssize_t listlen; + char list[FT_XATTR_SIZE]; + int i; + int count; + + i = 0; + ft_bzero(list, FT_XATTR_SIZE); + listlen = listxattr(path, list, FT_XATTR_SIZE, XATTR_NOFOLLOW); + if (listlen == -1) + return (-1); + count = 0; + while (i < listlen) + { + i += ft_strlen(list) + 1; + count++; + } + return (count); +} + +#else + +int ft_xattr_count(char *path) +{ + ssize_t listlen; + char list[FT_XATTR_SIZE]; + int i; + int count; + + i = 0; + ft_bzero(list, FT_XATTR_SIZE); + listlen = listxattr(path, list, FT_XATTR_SIZE); + if (listlen == -1) + return (-1); + count = 0; + while (i < listlen) + { + i += ft_strlen(list) + 1; + count++; + } + return (count); +} + +#endif diff --git a/42sh/libft/src/sys/ft_xattr_print.c b/42sh/libft/src/sys/ft_xattr_print.c new file mode 100644 index 00000000..e4d7e1a7 --- /dev/null +++ b/42sh/libft/src/sys/ft_xattr_print.c @@ -0,0 +1,69 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_xattr_print.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/03 18:00:43 by jhalford #+# #+# */ +/* Updated: 2017/03/05 16:48:20 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +#if defined __APPLE__ + +int ft_xattr_print(char *path) +{ + ssize_t listlen; + ssize_t valuelen; + char list[FT_XATTR_SIZE]; + char value[FT_XATTR_SIZE]; + int i; + + i = 0; + listlen = listxattr(path, list, FT_XATTR_SIZE, XATTR_NOFOLLOW); + if (listlen == -1) + return (1); + while (i < listlen) + { + valuelen = getxattr(path, list + i, value, + FT_XATTR_SIZE, 0, XATTR_NOFOLLOW); + if (valuelen == -1) + ft_printf("couldn't get value\n"); + else + ft_printf("%s:\n%s\n", list + i, value); + i += ft_strlen(list) + 1; + } + return (0); +} + +#else + +int ft_xattr_print(char *path) +{ + ssize_t listlen; + ssize_t valuelen; + char list[FT_XATTR_SIZE]; + char value[FT_XATTR_SIZE]; + int i; + + i = 0; + listlen = listxattr(path, list, FT_XATTR_SIZE); + if (listlen == -1) + return (1); + while (i < listlen) + { + valuelen = getxattr(path, list + i, value, + FT_XATTR_SIZE); + if (valuelen == -1) + ft_printf("couldn't get value\n"); + else + ft_printf("%s:\n%s\n", list + i, value); + i += ft_strlen(list) + 1; + } + return (0); +} + +#endif diff --git a/42sh/libft/src/sys/is_directory.c b/42sh/libft/src/sys/is_directory.c new file mode 100644 index 00000000..98ca4bad --- /dev/null +++ b/42sh/libft/src/sys/is_directory.c @@ -0,0 +1,22 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* is_directory.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/25 01:40:31 by jhalford #+# #+# */ +/* Updated: 2017/03/27 16:58:21 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +int is_directory(const char *path) +{ + struct stat path_stat; + + if (stat(path, &path_stat) != 0) + return (0); + return (S_ISDIR(path_stat.st_mode)); +} diff --git a/42sh/libft/src/sys/try_access.c b/42sh/libft/src/sys/try_access.c new file mode 100644 index 00000000..7567c337 --- /dev/null +++ b/42sh/libft/src/sys/try_access.c @@ -0,0 +1,24 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* open_access.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/25 01:10:56 by jhalford #+# #+# */ +/* Updated: 2017/03/27 19:46:21 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +int try_access(char *file, int exists, t_flag a_flag) +{ + if (exists && access(file, F_OK) != 0) + return (ERR_SET(E_SYS_NOFILE, file)); + else if (is_directory(file)) + return (ERR_SET(E_SYS_ISDIR, file)); + else if (access(file, F_OK) == 0 && access(file, a_flag) != 0) + return (ERR_SET(E_SYS_NOPERM, file)); + return (0); +} diff --git a/42sh/libft/src/time/ft_mytime_free.c b/42sh/libft/src/time/ft_mytime_free.c new file mode 100644 index 00000000..c8a89efc --- /dev/null +++ b/42sh/libft/src/time/ft_mytime_free.c @@ -0,0 +1,24 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_mytime_free.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/25 11:45:29 by jhalford #+# #+# */ +/* Updated: 2017/02/18 13:11:33 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void ft_mytime_free(t_mytime **time) +{ + ft_strdel(&(*time)->year); + ft_strdel(&(*time)->month); + ft_strdel(&(*time)->day); + ft_strdel(&(*time)->hour); + ft_strdel(&(*time)->min); + ft_strdel(&(*time)->sec); + ft_memdel((void **)time); +} diff --git a/42sh/libft/src/time/ft_mytime_get.c b/42sh/libft/src/time/ft_mytime_get.c new file mode 100644 index 00000000..ab8f25b3 --- /dev/null +++ b/42sh/libft/src/time/ft_mytime_get.c @@ -0,0 +1,31 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_getstrtime.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/25 11:34:56 by jhalford #+# #+# */ +/* Updated: 2017/03/21 15:42:19 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +t_mytime *ft_mytime_get(time_t epoch) +{ + char *date; + t_mytime *time; + + time = (t_mytime*)ft_malloc(sizeof(*time)); + date = ctime(&epoch); + date[ft_strlen(date) - 1] = 0; + time->year = ft_isdigit(date[20]) ? + ft_strsub(date, 20, 4) : ft_strsub(date, 24, 5); + time->month = ft_strsub(date, 4, 3); + time->day = ft_strsub(date, 8, 2); + time->hour = ft_strsub(date, 11, 2); + time->min = ft_strsub(date, 14, 2); + time->sec = ft_strsub(date, 17, 2); + return (time); +} diff --git a/42sh/libft/src/time/ft_time_isrecent.c b/42sh/libft/src/time/ft_time_isrecent.c new file mode 100644 index 00000000..ec195653 --- /dev/null +++ b/42sh/libft/src/time/ft_time_isrecent.c @@ -0,0 +1,24 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_time_isrecent.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/03 18:01:04 by jhalford #+# #+# */ +/* Updated: 2017/03/21 15:44:24 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +int ft_time_isrecent(time_t event) +{ + time_t now; + + now = time(&now); + if (now - event >= 0 && now - event <= 6 * 365 / 12 * 24 * 60 * 60) + return (1); + else + return (0); +} diff --git a/42sh/pdf/21sh.fr.pdf b/42sh/pdf/21sh.fr.pdf new file mode 100644 index 00000000..45e7b456 Binary files /dev/null and b/42sh/pdf/21sh.fr.pdf differ diff --git a/42sh/pdf/42sh.pdf b/42sh/pdf/42sh.pdf new file mode 100644 index 00000000..8bd54332 Binary files /dev/null and b/42sh/pdf/42sh.pdf differ diff --git a/42sh/pdf/minishell.fr.pdf b/42sh/pdf/minishell.fr.pdf new file mode 100644 index 00000000..f685854b Binary files /dev/null and b/42sh/pdf/minishell.fr.pdf differ diff --git a/42sh/sample/again.sh b/42sh/sample/again.sh new file mode 100644 index 00000000..624442dc --- /dev/null +++ b/42sh/sample/again.sh @@ -0,0 +1,6 @@ +echo "echo hello" >> sample/again.sh +echo hello +echo hello +echo hello +echo hello +echo hello diff --git a/42sh/sample/andor.sh b/42sh/sample/andor.sh new file mode 100644 index 00000000..6d83ae1a --- /dev/null +++ b/42sh/sample/andor.sh @@ -0,0 +1,8 @@ +pwd > file && pwd >> file || ls | cat && ls | cat >> file || ls +cat -e file + +sleep 2 +echo +echo "My script:" +echo +cat sample/andor.sh diff --git a/42sh/sample/brace.sh b/42sh/sample/brace.sh new file mode 100644 index 00000000..6f0a47f3 --- /dev/null +++ b/42sh/sample/brace.sh @@ -0,0 +1,9 @@ +{ ls ; pwd } > file +cat -e file + +sleep 2 +echo +echo "My sample :" +sleep 2 +echo +cat sample/brace.sh diff --git a/42sh/sample/case.sh b/42sh/sample/case.sh new file mode 100644 index 00000000..420f2235 --- /dev/null +++ b/42sh/sample/case.sh @@ -0,0 +1,16 @@ +case toto in + ( tutu ) echo PERDU ;; + ( titi ) echo PERDU ;; + ( toto ) case lala in + ( lolo ) echo PERDU ;; + ( lala ) echo GAGNE ;; + esac ;; +esac > file +cat -e file + +sleep 2 +echo +echo "My sample :" +sleep 2 +echo +cat sample/case.sh diff --git a/42sh/sample/comment.sh b/42sh/sample/comment.sh new file mode 100644 index 00000000..e4d6764f --- /dev/null +++ b/42sh/sample/comment.sh @@ -0,0 +1,9 @@ +ls # Da comment +pwd + +sleep 2 +echo +echo "My sample :" +sleep 2 +echo +cat sample/comment.sh diff --git a/42sh/sample/eof.sh b/42sh/sample/eof.sh new file mode 100644 index 00000000..e7c86456 --- /dev/null +++ b/42sh/sample/eof.sh @@ -0,0 +1,3 @@ +while [ 1 ] +do + ls diff --git a/42sh/sample/for.sh b/42sh/sample/for.sh new file mode 100644 index 00000000..2d6dbe87 --- /dev/null +++ b/42sh/sample/for.sh @@ -0,0 +1,13 @@ +for i in src/*/*.c +do + echo $i | cat -e > file + cat -e file >> another_file + cat -e another_file +done + +sleep 2 +echo +echo "My sample :" +sleep 2 +echo +cat sample/for.sh diff --git a/42sh/sample/func.sh b/42sh/sample/func.sh new file mode 100644 index 00000000..585f90a0 --- /dev/null +++ b/42sh/sample/func.sh @@ -0,0 +1,14 @@ +hello() ( + hello() ( + echo hello ; hello ) + hello +) + +hello + +sleep 2 +echo +echo "My sample :" +sleep 2 +echo +cat sample/func.sh diff --git a/42sh/sample/if.sh b/42sh/sample/if.sh new file mode 100644 index 00000000..6364a745 --- /dev/null +++ b/42sh/sample/if.sh @@ -0,0 +1,25 @@ +if false +then + echo PERDU +elif false +then + echo PERDU +elif true +then + if false + then + echo PERDU + elif + echo GAGNE + fi > file +else + echo PERDU +fi +cat -e file + +sleep 2 +echo +echo "My sample :" +sleep 2 +echo +cat sample/if.sh diff --git a/42sh/sample/mix.sh b/42sh/sample/mix.sh new file mode 100644 index 00000000..21b5a1dc --- /dev/null +++ b/42sh/sample/mix.sh @@ -0,0 +1,30 @@ +VAR=10 +if true +then + echo "Salut" ; echo "Correcteur" + while [ $VAR -gt 0 ] + do + until true + do + echo KO SI JE M AFFICHE + done + if true + then + echo OK SI JE M AFFICHE + elif [ -f Makefile ] + then + echo KO SI JE M AFFICHE + else + echo KO SI JE M AFFICHE + fi + echo "Encore un tour" + math VAR - 1 + done +fi + +sleep 2 +echo +echo "My sample :" +sleep 3 +echo +cat sample/mix.sh diff --git a/42sh/sample/muchloop.sh b/42sh/sample/muchloop.sh new file mode 100644 index 00000000..a4bd4192 --- /dev/null +++ b/42sh/sample/muchloop.sh @@ -0,0 +1,31 @@ +while [ 1 ] +do + while [ 1 ] + do + while [ 1 ] + do + while [ 1 ] + do + while [ 1 ] + do + while [ 1 ] + do + while [ 1 ] + do + while [ 1 ] + do + while [ 1 ] + do + while [ 1 ] + do + echo "SO MUCH LOOOOP" + done + done + done + done + done + done + done + done + done +done diff --git a/42sh/sample/script.sh b/42sh/sample/script.sh new file mode 100644 index 00000000..d45d0907 --- /dev/null +++ b/42sh/sample/script.sh @@ -0,0 +1,16 @@ +clear +YES=y +NO=n +echo "Welcome in 42Zash, new corrector, what is your login ?" + +until [ $REP == $YES ] +do + read -p "> " LOGIN + echo + read -p "Ok, fine, your login is $LOGIN, right ?(y/n) " REP + if [ $REP = $NO ] + then + echo + echo "Don't worry let's do it again" + fi +done diff --git a/42sh/sample/subshell.sh b/42sh/sample/subshell.sh new file mode 100644 index 00000000..8c386eed --- /dev/null +++ b/42sh/sample/subshell.sh @@ -0,0 +1,17 @@ +echo aaa \ + | (echo bbb 1; cat -e ;echo ccc 1) \ + | (echo bbb 2; cat -e ;echo ccc 2) \ + | (echo bbb 3; cat -e ;echo ccc 3) \ + | (echo bbb 4; cat -e ;echo ccc 4) \ + | (echo bbb 5; cat -e ;echo ccc 5) \ + | (echo bbb 6; cat -e ;echo ccc 6) \ + | (echo bbb 7; cat -e ;echo ccc 7) \ + | (echo bbb 8; cat -e ;echo ccc 8) \ + | (echo bbb 9; cat -e ;echo ccc 9) + + +sleep 2 +echo "My sample :" +echo +sleep 2 +cat sample/subshell.sh diff --git a/42sh/sample/toomuchdone.sh b/42sh/sample/toomuchdone.sh new file mode 100644 index 00000000..069b98ff --- /dev/null +++ b/42sh/sample/toomuchdone.sh @@ -0,0 +1,4 @@ +while [ 1 ] +do + ls +done done diff --git a/42sh/sample/until.sh b/42sh/sample/until.sh new file mode 100644 index 00000000..845b901e --- /dev/null +++ b/42sh/sample/until.sh @@ -0,0 +1,30 @@ +VAR1=0 +until [ $VAR1 -gt 10 ] +do + VAR2=0 + until [ $VAR2 -gt 10 ] + do + VAR3=0 + until [ $VAR3 -gt 10 ] + do + math VAR3 + 1 + echo "3rd is $VAR3" + done + math VAR2 + 1 + echo "2nd is $VAR2" + done + math VAR1 + 1 + echo "1st is $VAR1" + sleep 1 +done +echo +echo "VAR1: $VAR1" +echo "VAR2: $VAR2" +echo "VAR3: $VAR3" + +sleep 2 +echo +echo "My sample :" +sleep 2 +echo +cat sample/until.sh diff --git a/42sh/sample/var.sh b/42sh/sample/var.sh new file mode 100644 index 00000000..e1dca148 --- /dev/null +++ b/42sh/sample/var.sh @@ -0,0 +1,11 @@ +HELLO=WORLD HELLO=SALUT HELLO="BUENOS DIAS" +echo $HELLO +SALUT=$HELLO +echo $SALUT + +sleep 2 +echo +echo "My sample :" +sleep 2 +echo +cat sample/var.sh diff --git a/42sh/sample/while.sh b/42sh/sample/while.sh new file mode 100644 index 00000000..2f1448c6 --- /dev/null +++ b/42sh/sample/while.sh @@ -0,0 +1,24 @@ +VAR=10 +while + while [ $VAR -gt 0 ] + do + echo "Inside inner loop" | cat -e + math VAR - 1 + done + if [ $VAR -eq -42 ] + then + false + else + true + fi +do + echo "I'm the execution block" + VAR=-42 +done + +sleep 2 +echo +echo "My sample :" +sleep 3 +echo +cat sample/while.sh diff --git a/42sh/src/builtin/bt_env_opt.c b/42sh/src/builtin/bt_env_opt.c new file mode 100644 index 00000000..797d6945 --- /dev/null +++ b/42sh/src/builtin/bt_env_opt.c @@ -0,0 +1,37 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* bt_env_opt.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/25 20:39:54 by jhalford #+# #+# */ +/* Updated: 2017/03/25 21:21:09 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int bt_env_opt_i(char *opt_arg, t_env_data *data) +{ + (void)opt_arg; + ft_tabdel(&data->custom_env); + return (0); +} + +int bt_env_opt_u(char *opt_arg, t_env_data *data) +{ + int i; + char **env; + + if (!(env = data->custom_env)) + return (0); + i = -1; + while (env[++i]) + { + if (ft_strcmp(env[i], opt_arg) == '=' + && ft_strlen(opt_arg) == ft_strlenchr(env[i], '=')) + ft_sstrdel(env, i); + } + return (0); +} diff --git a/42sh/src/builtin/bt_read_get.c b/42sh/src/builtin/bt_read_get.c new file mode 100644 index 00000000..0953afe9 --- /dev/null +++ b/42sh/src/builtin/bt_read_get.c @@ -0,0 +1,58 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* bt_read_get.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/21 18:00:03 by jhalford #+# #+# */ +/* Updated: 2017/03/25 21:29:45 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int bt_read_getdelim(char *opt_arg, t_read *data) +{ + if (!opt_arg) + return (1); + if (data) + data->delim = *opt_arg; + return (0); +} + +int bt_read_getnchars(char *opt_arg, t_read *data) +{ + if (!opt_arg) + return (1); + if (data) + data->nchars = ft_atoi(opt_arg); + return (0); +} + +int bt_read_getprompt(char *opt_arg, t_read *data) +{ + if (!opt_arg) + return (1); + if (data) + data->prompt = opt_arg; + return (0); +} + +int bt_read_gettimeout(char *opt_arg, t_read *data) +{ + if (!opt_arg) + return (1); + if (data) + data->timeout = ft_atoi(opt_arg); + return (0); +} + +int bt_read_getfd(char *opt_arg, t_read *data) +{ + if (!opt_arg) + return (1); + if (data) + data->fd = ft_atoi(opt_arg); + return (0); +} diff --git a/42sh/src/builtin/bt_read_term.c b/42sh/src/builtin/bt_read_term.c new file mode 100644 index 00000000..5680eb6b --- /dev/null +++ b/42sh/src/builtin/bt_read_term.c @@ -0,0 +1,52 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* bt_read_term.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/25 16:02:05 by jhalford #+# #+# */ +/* Updated: 2017/03/29 15:02:36 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +struct termios bt_read_term(int init) +{ + static struct termios term; + + if (init) + tcgetattr(0, &term); + return (term); +} + +int bt_read_terminit(t_read *data) +{ + struct termios term; + + term = bt_read_term(1); + if (!(data->flag & BT_READ_INTER)) + return (0); + term.c_lflag &= ~(ICANON | ECHO); + term.c_cc[VTIME] = data->timeout * 10; + term.c_cc[VMIN] = data->timeout ? 0 : 1; + term.c_cc[VEOL] = data->delim; + if (tcsetattr(0, TCSANOW, &term) < 0) + { + SH_ERR("tcsetattr(): %s", strerror(errno)); + return (-1); + } + return (0); +} + +int bt_read_exit(t_read *data) +{ + struct termios term; + + ft_strdel(&data->input); + term = bt_read_term(0); + if (tcsetattr(0, TCSANOW, &term) < 0) + return (-1); + return (0); +} diff --git a/42sh/src/builtin/builtin_cd.c b/42sh/src/builtin/builtin_cd.c new file mode 100644 index 00000000..52ba258d --- /dev/null +++ b/42sh/src/builtin/builtin_cd.c @@ -0,0 +1,104 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* builtin_cd.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ariard +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/25 18:20:42 by ariard #+# #+# */ +/* Updated: 2017/03/29 11:03:20 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +#define CD_OPT_L (1 << 0) +#define CD_OPT_P (1 << 1) +#define HAS_CDOPT_P(x) (x & CD_OPT_P) +#define HAS_CDOPT_L(x) (x & CD_OPT_L) +#define CD_USAGE "usage: cd [-L|-P] [dir]" +#define CDERR_0 "cd: too many arguments" +#define CDERR_1 "cd %s not set" +#define CDERR_2 "cd : %s: No such file or directory" +#define CDERR_3 "cd : %s: Not a directory" +#define CDERR_4 "cd : %s: Permission denied" +#define CDERR_5 "cd : unable to proceed: %s" + +static t_cliopts g_cdopts[] = +{ + {'P', NULL, CD_OPT_P, CD_OPT_L, NULL, 0}, + {'L', NULL, CD_OPT_L, CD_OPT_P, NULL, 0}, + {0, NULL, 0, 0, NULL, 0}, +}; + +int cd_file_autorisations(char *target, int flag) +{ + (void)flag; + if (access(target, F_OK)) + return (SH_ERR(CDERR_2, target)); + if (!is_directory(target)) + return (SH_ERR(CDERR_3, target)); + if (access(target, X_OK)) + return (SH_ERR(CDERR_4, target)); + if (chdir(target)) + return (SH_ERR(CDERR_5, target)); + setwd("PWD"); + return (0); +} + +static char *cd_operand_exist(char *arg) +{ + char *tget; + + tget = NULL; + if (!arg) + { + if (!(tget = ft_strdup(ft_getenv(data_singleton()->env, "HOME")))) + return (SH_ERR(CDERR_1, "HOME") ? NULL : NULL); + } + else + { + if (!ft_strcmp(arg, "-")) + { + if (!(tget = ft_strdup(ft_getenv(data_singleton()->env, "OLDPWD")))) + return (SH_ERR(CDERR_1, "OLDPWD") ? NULL : NULL); + return (tget); + } + return (tget = ft_strdup(arg)); + } + return (tget); +} + +void setwd(char *var) +{ + char *cwd; + + cwd = getcwd(NULL, 0); + builtin_setenv(NULL, (char*[]){"cd", var, cwd, NULL}, NULL); + ft_strdel(&cwd); +} + +int builtin_cd(const char *path, char *const av[], + char *const envp[]) +{ + char *oldpwd; + char *target; + t_data_template data; + int ret; + + (void)envp; + (void)path; + data.flag = CD_OPT_L; + if (cliopts_get((char **)av, g_cdopts, &data)) + return (1); + if (data.av_data[0] && data.av_data[1]) + return (SH_ERR(CDERR_0) && SH_ERR(CD_USAGE)); + if (!(target = cd_operand_exist(*data.av_data))) + return (1); + oldpwd = getcwd(NULL, 0); + if (!(ret = cd_file_autorisations(target, data.flag))) + builtin_setenv(NULL, (char*[]){"cd", "OLDPWD", oldpwd, NULL}, NULL); + ft_strdel(&target); + ft_strdel(&oldpwd); + return (ret); +} diff --git a/42sh/src/builtin/builtin_echo.c b/42sh/src/builtin/builtin_echo.c new file mode 100644 index 00000000..8c6add7f --- /dev/null +++ b/42sh/src/builtin/builtin_echo.c @@ -0,0 +1,29 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* builtin_echo.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/28 14:21:41 by jhalford #+# #+# */ +/* Updated: 2017/03/21 15:21:05 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int builtin_echo(const char *path, char *const av[], char *const envp[]) +{ + (void)envp; + (void)path; + av++; + while (*av) + { + ft_printf("%s", *av); + av++; + if (*av) + ft_putchar(' '); + } + ft_putchar('\n'); + return (0); +} diff --git a/42sh/src/builtin/builtin_env.c b/42sh/src/builtin/builtin_env.c new file mode 100644 index 00000000..ad5da964 --- /dev/null +++ b/42sh/src/builtin/builtin_env.c @@ -0,0 +1,93 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* builtin_env.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/22 16:20:31 by gwojda #+# #+# */ +/* Updated: 2017/03/27 18:52:26 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +#define ENV_USAGE "env [-i] [name=value]... [utility [argument...]]" +#define ENV_NOFILE "env: %s: No such file or directory" +#define ENV_NOPERM "env: %s: Permission denied" + +static t_cliopts g_env_opts[] = +{ + {'i', NULL, 0, 0, &bt_env_opt_i, 0}, + {'u', NULL, 0, 0, &bt_env_opt_u, 1}, + {0, 0, 0, 0, 0, 0}, +}; + +static int bt_env_getcustom(char ***av, t_env_data *data) +{ + char **split; + + if (!av || !*av || !data) + return (1); + while (**av && ft_strchr(**av, '=')) + { + split = ft_strsplit(**av, '='); + bt_env_opt_u(split[0], data); + ft_tabdel(&split); + data->custom_env = ft_sstradd(data->custom_env, **av); + ++(*av); + } + return (0); +} + +static int bt_env_parse(t_env_data *data, char **av) +{ + data->flag = 0; + data->av_data = NULL; + data->custom_env = ft_sstrdup(data_singleton()->env); + if (cliopts_get(av, g_env_opts, data)) + return (1); + bt_env_getcustom(&data->av_data, data); + return (0); +} + +int display_env(char **av) +{ + if (av && *av) + { + ft_sstrprint(av, '\n'); + ft_putchar('\n'); + ft_tabdel(&av); + } + return (0); +} + +int builtin_env(const char *path, + char *const argv[], char *const envp[]) +{ + t_env_data dat; + int status; + pid_t pid; + + (void)envp; + if (bt_env_parse(&dat, (char**)argv)) + { + ft_sstrfree(dat.custom_env); + return (ft_perror("env") && SH_ERR("usage: %s", ENV_USAGE)); + } + if (!*dat.av_data) + return (display_env(dat.custom_env)); + else if ((pid = fork()) == 0) + { + if (!(path = ft_strchr(dat.av_data[0], '/') ? ft_strdup(dat.av_data[0]) + : ft_hash(dat.av_data[0])) || access(path, F_OK) != 0) + exit(SH_ERR(ENV_NOFILE, dat.av_data[0])); + if (is_directory(path) || access(path, X_OK) != 0) + exit(SH_ERR(ENV_NOPERM, dat.av_data[0])); + execve(path, dat.av_data, dat.custom_env); + } + waitpid(pid, &status, 0); + ft_sstrfree(dat.custom_env); + tcsetpgrp(STDIN, data_singleton()->jobc.shell_pgid); + return (WIFEXITED(status) ? WEXITSTATUS(status) : 128 + WTERMSIG(status)); +} diff --git a/42sh/src/builtin/builtin_exit.c b/42sh/src/builtin/builtin_exit.c new file mode 100644 index 00000000..8ef2c609 --- /dev/null +++ b/42sh/src/builtin/builtin_exit.c @@ -0,0 +1,44 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* builtin_exit.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/28 14:28:41 by jhalford #+# #+# */ +/* Updated: 2017/03/24 23:35:26 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +#define EXITERR_0 "exit: numeric argument required" +#define EXITERR_1 "exit: too many argument required" + +int builtin_exit(const char *path, char *const av[], char *const envp[]) +{ + int status; + static int notified = 0; + + (void)envp; + (void)path; + if (SH_HAS_JOBC(data_singleton()->opts) && !notified) + { + notified = 1; + if (has_stopped_job() || has_running_job()) + return (SH_ERR("There are running and/or stopped jobs")); + } + if (av && av[1] && !ft_stris(av[1], ft_isdigit) && (status = 255)) + SH_ERR(EXITERR_0); + else if (av && av[0] && av[1] && av[2]) + return (SH_ERR(EXITERR_1)); + else + status = (av && av[1]) ? + ft_atoi(av[1]) : ft_atoi(ft_getenv(data_singleton()->env, "?")); + if (SH_IS_INTERACTIVE(data_singleton()->opts)) + tcsetattr(STDIN, TCSANOW, &data_singleton()->jobc.shell_tmodes); + job_hup_all(); + data_exit(); + 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..f663e725 --- /dev/null +++ b/42sh/src/builtin/builtin_export.c @@ -0,0 +1,69 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* builtin_export.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/15 11:39:37 by gwojda #+# #+# */ +/* Updated: 2017/03/25 01:39:34 by wescande ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +#define BT_EXPORT_LP (1 << 0) +#define EXPORT_USAGE "usage: export [name[=value] ...] or export -p" + +static t_cliopts g_export_opts[] = +{ + {'p', NULL, BT_EXPORT_LP, 0, NULL, 0}, + {0, NULL, 0, 0, NULL, 0}, +}; + +int bt_export_print(void) +{ + char **env; + char *equal; + + env = data_singleton()->env; + while (*env) + { + if ((equal = ft_strchr(*env, '='))) + ft_printf("export %s\n", *env); + else + ft_printf("export %s\n", *env); + env++; + } + return (0); +} + +int builtin_export( + const char *path, char *const av[], char *const envp[]) +{ + char *equal; + t_btexport data; + + (void)path; + data.flag = 0; + if (cliopts_get((char**)av, g_export_opts, &data)) + return (ft_perror("export") && SH_ERR(EXPORT_USAGE)); + if (data.flag & BT_EXPORT_LP) + return (bt_export_print()); + av = data.av_data; + if (!(data.flag = 0) && !*av) + bt_export_print(); + while (*av) + { + equal = ft_strchr(*av, '='); + if (equal) + *(equal++) = 0; + else + equal = ft_getenv(data_singleton()->local_var, *av); + data.flag += builtin_setenv("internal", (char*[]){"export", *av, + equal}, envp); + builtin_unsetenv("internal", (char*[]){"local", *av, NULL}, NULL); + av++; + } + return (data.flag ? 1 : 0); +} diff --git a/42sh/src/builtin/builtin_func.c b/42sh/src/builtin/builtin_func.c new file mode 100644 index 00000000..1c03a2b1 --- /dev/null +++ b/42sh/src/builtin/builtin_func.c @@ -0,0 +1,40 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* builtin_func.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/24 15:03:02 by wescande #+# #+# */ +/* Updated: 2017/03/25 15:08:37 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +#define FUNC_USAGE "func" + +int builtin_func(const char *path, + char *const argv[], char *const envp[]) +{ + t_list *list; + char **name; + t_btree **ast; + + (void)envp; + (void)path; + if (!argv || !argv[0] || argv[1]) + return (SH_ERR("usage: %s", FUNC_USAGE) ? 1 : 1); + list = data_singleton()->lst_func; + while (list) + { + if (!(ast = list->content)) + return (SH_ERR("unexpected error")); + name = token_to_argv(((t_astnode *)(*ast)->item)->data.cmd.token, 1); + if (name && name[0]) + ft_putendl(name[0]); + ft_tabdel(&name); + list = list->next; + } + return (0); +} diff --git a/42sh/src/builtin/builtin_hash.c b/42sh/src/builtin/builtin_hash.c new file mode 100644 index 00000000..18aa0645 --- /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/03/20 14:03:30 by wescande ### ########.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 (!av || ft_hash_opt(av)) + return (1); + 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..1c315ee8 --- /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/03/20 14:04:02 by wescande ### ########.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_math.c b/42sh/src/builtin/builtin_math.c new file mode 100644 index 00000000..d50788bf --- /dev/null +++ b/42sh/src/builtin/builtin_math.c @@ -0,0 +1,62 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* builtin_math.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ariard +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/17 18:54:00 by ariard #+# #+# */ +/* Updated: 2017/03/23 17:16:43 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +#define MATHERR_0 "usage: math variable operator(add/sub/mul/div/mod) operand" +#define MATHERR_2 "math: %c: invalid operator" +#define MATHERR_3 "math: %s: operand must be digits only" +#define MATHERR_4 "math: division by 0" +#define MATHERR_5 "math: modulo by 0" + +static char *do_math(char *value, char operator, char *operand) +{ + long ope1; + long ope2; + + ope1 = ft_atoi(value); + ope2 = ft_atoi(operand); + if ((operator == '/') && ope2 == 0) + return (SH_ERR(MATHERR_4) ? NULL : NULL); + if ((operator == '%') && ope2 == 0) + return (SH_ERR(MATHERR_5) ? NULL : NULL); + ope1 = (operator == '+') ? ope1 + ope2 : ope1; + ope1 = (operator == '-') ? ope1 - ope2 : ope1; + ope1 = (operator == '/') ? ope1 / ope2 : ope1; + ope1 = (operator == '*') ? ope1 * ope2 : ope1; + ope1 = (operator == '%') ? ope1 % ope2 : ope1; + return (ft_itoa(ope1)); +} + +int builtin_math(const char *path, char *const av[], char *const envp[]) +{ + char *value; + char operator; + char *operand; + + (void)path; + (void)envp; + if (!av || !av[0] || !av[1] || !av[2] || !av[3] || av[4]) + return (SH_ERR(MATHERR_0)); + value = ft_getenv(data_singleton()->local_var, av[1]); + operator = av[2][0]; + if (!(ft_strchr("+-/*%", operator))) + return (SH_ERR(MATHERR_2, operator)); + operand = av[3]; + if (!ft_stris(operand, &ft_isdigit)) + return (SH_ERR(MATHERR_3, operand)); + if (!(value = do_math(value, operator, operand))) + return (1); + builtin_setenv("setenv", (char *[]){"local", av[1], value, 0}, NULL); + ft_strdel(&value); + return (0); +} diff --git a/42sh/src/builtin/builtin_read.c b/42sh/src/builtin/builtin_read.c new file mode 100644 index 00000000..5b2d0495 --- /dev/null +++ b/42sh/src/builtin/builtin_read.c @@ -0,0 +1,120 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* builtin_read.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/20 15:01:45 by jhalford #+# #+# */ +/* Updated: 2017/03/29 15:19:11 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +#define US_READ "read [-ers] [-u fd] [-t timeout] [-p prompt]" +#define US_READ_1 " [-n nchars] [-d delim] [name ...]" + +t_cliopts g_read_opts[] = +{ + {'d', NULL, BT_READ_LD, 0, bt_read_getdelim, 1}, + {'n', NULL, BT_READ_LN, 0, bt_read_getnchars, 1}, + {'p', NULL, BT_READ_LP, 0, bt_read_getprompt, 1}, + {'r', NULL, BT_READ_LR, 0, NULL, 0}, + {'s', NULL, BT_READ_LS, 0, NULL, 0}, + {'t', NULL, BT_READ_LT, 0, bt_read_gettimeout, 1}, + {'u', NULL, BT_READ_LU, 0, bt_read_getfd, 1}, + {0, 0, 0, 0, 0, 0}, +}; + +int bt_read_init(t_read *data, char **av) +{ + data->flag = 0; + data->delim = '\n'; + data->nchars = -1; + data->prompt = NULL; + data->fd = 0; + data->timeout = 0; + data->input = NULL; + if (isatty(STDIN)) + data->flag |= BT_READ_INTER; + if ((cliopts_get(av, g_read_opts, data))) + return (ft_perror("read")); + if (bt_read_terminit(data) < 0) + exit(1); + return (0); +} + +int bt_read_loop(t_read *data) +{ + int i; + int esc; + int ret; + char buf[2]; + + esc = 0; + if (!(i = 0) && data->prompt && (data->flag & BT_READ_INTER)) + ft_putstr(data->prompt); + while (42) + { + if ((ret = read(data->fd, buf, 4)) <= 0) + return (ret); + buf[ret] = 0; + ft_putchar(data->flag & BT_READ_LS ? 0 : *buf); + if (!esc && *buf == data->delim) + break ; + esc = esc ? 0 : !(data->flag & BT_READ_LR) && (*buf == '\\'); + ft_strappend(&data->input, buf); + if (*buf == '\n' && !(data->flag & + (BT_READ_LR | BT_READ_LS | BT_READ_INTER))) + ft_putstr("> "); + if ((data->flag & BT_READ_LN) && ++i >= data->nchars) + break ; + } + return (0); +} + +int bt_read_assign(t_read *data) +{ + char *input; + char **names; + char *ifs; + char *tok; + + input = data->input; + names = *data->names ? data->names : (char*[]){"REPLY", NULL}; + ifs = ft_getenv(data_singleton()->local_var, "IFS"); + if (!names[1]) + ifs = NULL; + tok = ft_strtok(input, ifs); + while (*names) + { + if ((builtin_setenv("setenv", (char*[]){"read", *names, tok}, NULL))) + return (1); + ifs = (++names)[1] ? ifs : NULL; + tok = ft_strtok(NULL, ifs); + } + return (0); +} + +int builtin_read(const char *path, char *const av[], char *const envp[]) +{ + t_read data; + int ret; + + (void)path; + (void)envp; + ret = 0; + if ((ret = bt_read_init(&data, (char **)av)) != 0) + SH_ERR("usage: %s%s", US_READ, US_READ_1); + else if ((ret = bt_read_loop(&data))) + { + ; + } + else if (data.input && (ret = bt_read_assign(&data))) + { + ; + } + bt_read_exit(&data); + return (ret); +} diff --git a/42sh/src/builtin/builtin_setenv.c b/42sh/src/builtin/builtin_setenv.c new file mode 100644 index 00000000..3f79f8e2 --- /dev/null +++ b/42sh/src/builtin/builtin_setenv.c @@ -0,0 +1,67 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* builtin_setenv.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/28 14:25:17 by jhalford #+# #+# */ +/* Updated: 2017/03/24 23:14:52 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +#define SETERR_0 "%s: not an identifier: %s" + +static int assign_var(char *const av[], char ***env) +{ + char *str; + int i; + + i = -1; + str = ft_str3join(av[1], "=", av[2]); + while ((*env) && (*env)[++i]) + { + if (ft_strcmp((*env)[i], av[1]) == '=' + && ft_strlen(av[1]) == ft_strlenchr((*env)[i], '=')) + { + ft_strdel(&(*env)[i]); + (*env)[i] = str; + return (0); + } + } + *env = ft_sstradd(*env, str); + ft_strdel(&str); + return (0); +} + +int builtin_setenv(const char *path, + char *const av[], char *const envp[]) +{ + char ***env; + char *esc; + int ret; + + (void)path; + (void)envp; + if (!av || !av[0]) + return (1); + env = (ft_strcmp(av[0], "local") == 0) ? &data_singleton()->local_var : + &data_singleton()->env; + if (!av[1]) + { + ft_sstrprint(*env, '\n'); + ft_putchar('\n'); + } + else + { + esc = ft_strnew((ft_strlen(av[1]) >> 3) + 1); + ret = word_is_assignment((char *[]){av[1], (esc + 1)}); + ft_strdel(&esc); + if (!ret && ft_strcmp(av[1], "?")) + return (SH_ERR(SETERR_0, av[0], av[1])); + assign_var(av, env); + } + return (0); +} diff --git a/42sh/src/builtin/builtin_unset.c b/42sh/src/builtin/builtin_unset.c new file mode 100644 index 00000000..d335e53e --- /dev/null +++ b/42sh/src/builtin/builtin_unset.c @@ -0,0 +1,26 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* builtin_unset.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/15 11:43:34 by gwojda #+# #+# */ +/* Updated: 2017/03/20 14:27:43 by wescande ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int builtin_unset(const char *path, char *const av[], char *const envp[]) +{ + char *tmp; + char **av_tmp; + + tmp = av[0]; + av_tmp = (char **)av; + av_tmp[0] = "local"; + builtin_unsetenv(path, av, envp); + av_tmp[0] = tmp; + return (builtin_unsetenv(path, av, envp)); +} diff --git a/42sh/src/builtin/builtin_unsetenv.c b/42sh/src/builtin/builtin_unsetenv.c new file mode 100644 index 00000000..22bea5d2 --- /dev/null +++ b/42sh/src/builtin/builtin_unsetenv.c @@ -0,0 +1,40 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* builtin_unsetenv.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/28 14:29:17 by jhalford #+# #+# */ +/* Updated: 2017/03/24 22:59:17 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int builtin_unsetenv(const char *path, char *const av[], char *const envp[]) +{ + int i; + int j; + char ***env; + + (void)envp; + (void)path; + env = ft_strcmp(av[0], "local") == 0 ? + &data_singleton()->local_var : &data_singleton()->env; + i = 1; + while (av[i]) + { + j = 0; + while (*env && (*env)[j]) + { + if (ft_strcmp((*env)[j], av[i]) == '=' + && ft_strlen(av[i]) == ft_strlenchr((*env)[j], '=')) + ft_sstrdel(*env, j); + else + j++; + } + i++; + } + return (0); +} diff --git a/42sh/src/builtin/is_builtin.c b/42sh/src/builtin/is_builtin.c new file mode 100644 index 00000000..65a87bcc --- /dev/null +++ b/42sh/src/builtin/is_builtin.c @@ -0,0 +1,48 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* is_builtin.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/13 13:09:57 by jhalford #+# #+# */ +/* Updated: 2017/03/27 16:03:10 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +t_stof g_builtin[] = +{ + {"echo", &builtin_echo}, + {"cd", &builtin_cd}, + {"export", &builtin_export}, + {"unset", &builtin_unset}, + {"setenv", &builtin_setenv}, + {"local", &builtin_setenv}, + {"unsetenv", &builtin_unsetenv}, + {"env", &builtin_env}, + {"exit", &builtin_exit}, + {"jobs", &builtin_jobs}, + {"fg", &builtin_fg}, + {"bg", &builtin_bg}, + {"read", &builtin_read}, + {"hash", &builtin_hash}, + {"history", &builtin_history}, + {"math", &builtin_math}, + {"func", &builtin_func}, + {NULL, NULL}, +}; + +t_execf *is_builtin(t_process *p) +{ + int i; + + i = -1; + while (g_builtin[++i].name) + { + if (ft_strcmp(g_builtin[i].name, p->data.cmd.av[0]) == 0) + return (g_builtin[i].f); + } + return (NULL); +} diff --git a/42sh/src/completion/c_arrow.c b/42sh/src/completion/c_arrow.c new file mode 100644 index 00000000..00b9328f --- /dev/null +++ b/42sh/src/completion/c_arrow.c @@ -0,0 +1,99 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* c_arrow.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: alao +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/10 09:04:42 by alao #+# #+# */ +/* Updated: 2017/03/17 18:12:31 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "completion.h" + +/* +** Calculate the offset id value from the current one relative to the list size. +** lst_modulo is the number in element in the last column of the list that is +** not perfectly in the same size. +*/ + +static int c_idsolver(t_comp *c, int ids, int ids_bk) +{ + int lst_modulo; + + lst_modulo = c->lst->prev->id % c->c_line; + if (lst_modulo == 0) + lst_modulo = c->c_line; + if (ids > c->lst->prev->id) + { + ids -= c->lst->prev->id; + if (ids_bk < ((c->lst->prev->id - lst_modulo) + 1)) + ids = ids + lst_modulo; + else + ids = ids - (c->c_line - lst_modulo); + } + else if (ids < c->lst->id) + { + if (ids_bk <= lst_modulo) + ids = (c->lst->prev->id - lst_modulo) + ids_bk; + else + ids = c->lst->prev->id - (ids * -1) - lst_modulo; + if (ids < c->lst->id) + ids = 1; + } + return (ids); +} + +/* +** Determine the movement in the list by retrieving the current id selected in +** the list and add/substract the value depending on the keypress (left/right). +** Call for c_idsolver() to adjust this value and cycle in the list to reassign +** the correct element to cursor position. +*/ + +static void c_arrow_multi(t_comp *c, long int keypress) +{ + t_clst *ptr; + int ids; + int ids_bk; + + ids = 0; + ptr = c->lst; + while (!ptr->cursor) + ptr = ptr->next; + ptr->cursor = 0; + ids = ptr->id; + ids_bk = ids; + (keypress == 4479771) ? (ids -= c->c_line) : (0); + (keypress == 4414235) ? (ids += c->c_line) : (0); + ids = c_idsolver(c, ids, ids_bk); + ptr = c->lst; + while (ptr->id != ids) + ptr = ptr->next; + ptr->cursor = 1; +} + +/* +** Arrow support for moving inside the list of the completion. +** If the keypress is left/right, c_arrow_multi() is called. Else the list is +** just read until the cursor is found and the next/prev is reassigned as +** selected. +*/ + +void c_arrow(t_comp *c, long int keypress) +{ + t_clst *ptr; + + ptr = c->lst; + if (keypress == 4479771 || keypress == 4414235) + c_arrow_multi(c, keypress); + else + { + while (!ptr->cursor) + ptr = ptr->next; + ptr->cursor = 0; + (keypress == 4283163) ? (ptr->prev->cursor = 1) : (0); + (keypress == 4348699) ? (ptr->next->cursor = 1) : (0); + } +} diff --git a/42sh/src/completion/c_clear.c b/42sh/src/completion/c_clear.c new file mode 100644 index 00000000..67f8b688 --- /dev/null +++ b/42sh/src/completion/c_clear.c @@ -0,0 +1,70 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* c_clear.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: alao +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/10 11:37:43 by alao #+# #+# */ +/* Updated: 2017/03/23 18:55:43 by gwojda ### ########.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; + + if (c->lst == NULL) + return (0); + 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; + + if (s->comp == NULL) + return (0); + 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; + data_singleton()->comp = NULL; + return (0); +} diff --git a/42sh/src/completion/c_find_abspath.c b/42sh/src/completion/c_find_abspath.c new file mode 100644 index 00000000..15501de0 --- /dev/null +++ b/42sh/src/completion/c_find_abspath.c @@ -0,0 +1,41 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* c_find_abspath.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/09 16:54:59 by gwojda #+# #+# */ +/* Updated: 2017/03/23 19:07:47 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "completion.h" + +/* +** Process the absolute path for the completion. +*/ + +void c_seek_abs_path(t_comp *c, char *current_word) +{ + char *tmp; + int len; + + len = ft_strrchr(current_word, '/') - current_word + 1; + if (len < 0) + return ; + if (c->cpath) + ft_strdel(&c->cpath); + c->cpath = ft_strndup(current_word, len); + if (current_word[0] == '~') + { + tmp = c->cpath; + c->cpath = ft_str3join(getenv("HOME"), "/", c->cpath + 2); + free(tmp); + } + !c->match ? c->match = ft_strdupi_w(ft_strrchr(c->rcmd, '/') + 1) : 0; + c_parser(c, c->cpath, c->match); + if (c->lst == NULL || c->lst == c->lst->prev) + c_exclusion_folder(c); + c_lst_id(data_singleton()->comp); +} diff --git a/42sh/src/completion/c_find_binary.c b/42sh/src/completion/c_find_binary.c new file mode 100644 index 00000000..59344970 --- /dev/null +++ b/42sh/src/completion/c_find_binary.c @@ -0,0 +1,40 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* c_find_binary.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: alao +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/09 13:30:57 by alao #+# #+# */ +/* Updated: 2017/03/23 19:07:52 by gwojda ### ########.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, ':'); + if (c->match == NULL) + 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); + c_lst_id(data_singleton()->comp); + return (0); +} diff --git a/42sh/src/completion/c_find_env.c b/42sh/src/completion/c_find_env.c new file mode 100644 index 00000000..0ad450d1 --- /dev/null +++ b/42sh/src/completion/c_find_env.c @@ -0,0 +1,55 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* c_find_env.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/09 15:50:24 by gwojda #+# #+# */ +/* Updated: 2017/03/27 18:50:23 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "completion.h" + +/* +** Create a new list node and add it by calling c_add_to_lst. +*/ + +static int c_addnode(t_comp *c, char *value) +{ + t_clst *tmp; + + if (!(tmp = (t_clst *)ft_malloc(sizeof(t_clst)))) + return (-1); + tmp->name = value; + tmp->len = ft_strlen(tmp->name); + tmp->type = 10; + tmp->cursor = 0; + c_add_to_lst(c, tmp); + return (0); +} + +/* +** Search in the env for matching element and add them to the list if matched. +*/ + +int c_seek_env(t_comp *c, char *current_word) +{ + char **env; + int i; + int m_len; + + i = 0; + env = data_singleton()->env; + c->match = ft_strdupi_w(current_word + 1); + m_len = ft_strlen(c->match); + while (env[i]) + { + if (!ft_strncmp(c->match, env[i], m_len) && env[i][m_len] != '=') + c_addnode(c, ft_strndup(env[i], ft_strchr(env[i], '=') - env[i])); + ++i; + } + c_lst_id(data_singleton()->comp); + return (0); +} diff --git a/42sh/src/completion/c_find_files.c b/42sh/src/completion/c_find_files.c new file mode 100644 index 00000000..fa575bf7 --- /dev/null +++ b/42sh/src/completion/c_find_files.c @@ -0,0 +1,110 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* c_find_files.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: alao +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/09 13:31:21 by alao #+# #+# */ +/* Updated: 2017/03/23 19:08:08 by gwojda ### ########.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. +*/ + +int c_exclusion_folder(t_comp *c) +{ + DIR *rep; + char *tmp; + char *tmp2; + + tmp = ft_strjoin(c->cpath, c->match); + tmp2 = NULL; + if ((rep = opendir(tmp)) && (!closedir(rep))) + { + tmp ? ft_memdel((void *)&tmp) : (0); + if (c->rcmd[ft_strlen(c->rcmd) - 1] == '/' + || c->rcmd[ft_strlen(c->rcmd) - 1] == '.') + { + c_clear(data_singleton()); + return (0); + } + tmp2 = ft_strjoin(c->match, "/"); + c_updater(c, tmp2); + tmp2 ? ft_memdel((void *)&tmp2) : (0); + return (1); + } + tmp ? ft_memdel((void *)&tmp) : (0); + 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] && 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); + tmp ? ft_memdel((void *)&tmp) : (0); + return (rt); +} + +/* +** Files searching +*/ + +int c_seek_files(t_data *s, t_comp *c, char *current_word) +{ + char *path; + + (void)s; + if (c->rcmd[0] == '.') + { + c->cpath = ft_strdup("./"); + c->match = ft_strdup(current_word); + } + if (c->cpath == NULL) + { + path = c_slicer(c); + c->match = ft_strdup(current_word); + 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->isrematch == 0) + c_exclusion_folder(c); + else if ((c->lst && (c->lst == c->lst->next)) && c->isrematch == 0) + { + if (c->match && ft_strequ(c->match, c->lst->name)) + c_exclusion_folder(c); + } + c_lst_id(data_singleton()->comp); + return (0); +} diff --git a/42sh/src/completion/c_init.c b/42sh/src/completion/c_init.c new file mode 100644 index 00000000..ccb5fc6e --- /dev/null +++ b/42sh/src/completion/c_init.c @@ -0,0 +1,100 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* c_init.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: alao +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/09 11:21:16 by alao #+# #+# */ +/* Updated: 2017/03/22 15:12:03 by gwojda ### ########.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) - st); + 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->win_y = win.ws_row; + c->m_size = data_singleton()->line.prompt_size; + c->m_size += ft_strlen(data_singleton()->line.input); + c->m_size = (c->m_size / c->win_y); + c->m_size = c->win_y - c->m_size - 1; + c->pos_x = 1; + c->pos_y = 1; + c->cutpoint = 0; + c->between = NULL; + c->isfolder = 0; + c->isrematch = 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 *)ft_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_match.c b/42sh/src/completion/c_match.c new file mode 100644 index 00000000..12438105 --- /dev/null +++ b/42sh/src/completion/c_match.c @@ -0,0 +1,95 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* c_match.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: alao +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/10/15 13:27:14 by alao #+# #+# */ +/* Updated: 2017/03/28 09:09:56 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +/* +** Check char +*/ + +int c_is_delim(char c) +{ + if (c == ' ' || c == '<' || c == '>' || c == '\n' || c == ';') + return (1); + return (0); +} + +/* +** strdupi +*/ + +char *c_strdupi(char *s, int (*f)(char)) +{ + int i; + char *str; + + i = 0; + while (s[i] && !(*f)(s[i])) + i++; + str = (char *)ft_malloc(sizeof(char) * (i + 1)); + if (str) + { + str[i--] = '\0'; + while (i >= 0) + { + str[i] = s[i]; + i--; + } + } + return (str); +} + +/* +** Seek the current word. +*/ + +static char *c_current_words(void) +{ + size_t pos; + char *str; + + pos = data_singleton()->line.pos; + str = data_singleton()->line.input; + if (pos && c_is_delim(str[pos])) + --pos; + while (pos && !c_is_delim(str[pos])) + --pos; + if (c_is_delim(str[pos])) + ++pos; + return (c_strdupi(str + pos, &c_is_delim)); +} + +/* +** Start the parsing for the autocompletion. +*/ + +int c_matching(t_data *s, t_comp *c) +{ + char *current_word; + + current_word = c_current_words(); + if (ft_strchr(current_word, '/')) + c_seek_abs_path(c, current_word); + else if (ft_strchr(current_word, '$')) + c_seek_env(c, current_word); + else if (current_word[0] != '.' && !(ft_strchr(c->rcmd, ' '))) + c_seek_binary(s, c); + else + c_seek_files(s, c, current_word); + ft_strdel(¤t_word); + if (s->comp && s->comp->lst) + { + c_sizing(c); + return (1); + } + return (0); +} diff --git a/42sh/src/completion/c_match_glob.c b/42sh/src/completion/c_match_glob.c new file mode 100644 index 00000000..955ec506 --- /dev/null +++ b/42sh/src/completion/c_match_glob.c @@ -0,0 +1,116 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* c_match_glob.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/08 17:20:01 by gwojda #+# #+# */ +/* Updated: 2017/03/29 16:09:59 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "completion.h" + +/* +** Recreate the command from the globbing module responds. +*/ + +static void c_replace_globbing(char **glob, size_t start, size_t pos) +{ + char *ref_next; + char *ref_mid; + char *ref_prev; + char *str; + + str = data_singleton()->line.input; + while (str[pos] && str[pos] != ' ') + ++pos; + while (str[pos] && str[pos] == ' ') + ++pos; + ref_prev = ft_strndup(str, start); + ref_mid = ft_sstrtostr(glob, " "); + ref_next = ft_strdup(str + pos); + data_singleton()->line.input = ft_str3join(ref_prev, ref_mid, ref_next); + if (ft_strlen(data_singleton()->line.input) > SIZE_LINE) + { + ft_strdel(&data_singleton()->line.input); + data_singleton()->line.input = str; + } + else + ft_strdel(&str); + ft_strdel(&ref_prev); + ft_strdel(&ref_mid); + ft_strdel(&ref_next); + ft_sstrfree(glob); +} + +/* +** 42 norme. Readjust the position. +*/ + +static int c_glob_pos(char *str, size_t pos) +{ + str = data_singleton()->line.input; + pos = data_singleton()->line.pos; + if (!str) + return (-1); + if (pos && (str[pos] == ' ' || str[pos] == ';')) + --pos; + while (pos && str[pos] != ' ' && str[pos] != ';') + --pos; + if (str[pos] == ' ' || str[pos] == ';') + ++pos; + return (pos); +} + +/* +** check glob return and free +*/ + +static int c_check_glob(char **ss_glob, char *current_word, + unsigned char *glob_echap, size_t pos) +{ + char *str; + + str = data_singleton()->line.input; + free(current_word); + free(glob_echap); + if (!ss_glob || !*ss_glob || !**ss_glob || + !ft_strncmp(str + pos, *ss_glob, ft_strlen(*ss_glob))) + { + ft_sstrfree(ss_glob); + return (1); + } + return (0); +} + +/* +** Match for globbing feature. +*/ + +int c_glob_matching(void) +{ + char *current_word; + char **ss_glob; + unsigned char *glob_echap; + char *str; + long pos; + + str = data_singleton()->line.input; + if ((pos = c_glob_pos(NULL, 0)) == -1) + return (0); + current_word = ft_strdupi_w(str + pos); + if (current_word[0] == '~') + { + free(current_word); + return (0); + } + glob_echap = (unsigned char *)ft_strnew(ft_strlen(str) >> 3); + ft_bzero(glob_echap, ft_strlen(str) >> 3); + ss_glob = glob(current_word, glob_echap, glob_echap, 1); + if (c_check_glob(ss_glob, current_word, glob_echap, pos)) + return (0); + c_replace_globbing(ss_glob, pos, data_singleton()->line.pos); + return (1); +} diff --git a/42sh/src/completion/c_match_update.c b/42sh/src/completion/c_match_update.c new file mode 100644 index 00000000..1d09528d --- /dev/null +++ b/42sh/src/completion/c_match_update.c @@ -0,0 +1,94 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* c_match_update.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: alao +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/15 12:03:30 by alao #+# #+# */ +/* Updated: 2017/03/28 16:13:46 by wescande ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "completion.h" + +static char *c_current_words(void) +{ + size_t pos; + char *str; + + pos = data_singleton()->line.pos; + str = data_singleton()->line.input; + if (pos && c_is_delim(str[pos])) + --pos; + while (pos && !c_is_delim(str[pos])) + --pos; + if (c_is_delim(str[pos])) + ++pos; + return (c_strdupi(str + pos, &c_is_delim)); +} + +/* +** 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]; + char *dump; + + 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); + dump = c_current_words(); + if (!(ft_strchr(dump, '$'))) + 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); + dump ? ft_memdel((void *)&dump) : (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) +{ + t_data *s; + + s = data_singleton(); + if (ft_isascii(keypress)) + { + c->isrematch = 1; + c_term_clear(c); + c_refresh_match(c, keypress); + c_clear_lst(c); + ft_print(keypress, &s->line.input, &s->line.pos); + c_matching(s, c); + if (s->comp && c->lst == NULL) + c_clear(s); + else if (s->comp && c->lst == c->lst->next) + return (ft_putchar('\b') + 1); + return (1); + } + else + { + c_term_clear(c); + c_clear(s); + } + return (0); +} diff --git a/42sh/src/completion/c_misc.c b/42sh/src/completion/c_misc.c new file mode 100644 index 00000000..0535d8f3 --- /dev/null +++ b/42sh/src/completion/c_misc.c @@ -0,0 +1,101 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* c_misc.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: alao +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/16 22:17:10 by alao #+# #+# */ +/* Updated: 2017/03/23 16:11:29 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "completion.h" + +/* +** Count the number of time char c is in str. +*/ + +static size_t ft_strxchr(char *str, char c) +{ + size_t rt; + + rt = 0; + while (*str) + { + if (*str == c) + rt++; + str++; + } + return (rt); +} + +/* +** Add escape char \ for char to_escape. +*/ + +char *ft_add_escape(char *str, char to_escape) +{ + char *rt; + int i; + int j; + + if (!str) + return (NULL); + if (!ft_strxchr(str, ' ')) + return (ft_strdup(str)); + rt = ft_strnew(ft_strlen(str) + ft_strxchr(str, to_escape)); + i = 0; + j = 0; + while (str[i]) + { + if (str[i] == to_escape) + { + i++; + rt[j++] = '\\'; + rt[j++] = ' '; + } + else + rt[j++] = str[i++]; + } + return (rt); +} + +/* +** 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..8b5faf28 --- /dev/null +++ b/42sh/src/completion/c_output.c @@ -0,0 +1,131 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* c_output.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: alao +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/03 13:10:38 by alao #+# #+# */ +/* Updated: 2017/03/23 19:00:05 by gwojda ### ########.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->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; + char *alter; + + tmp = NULL; + rt = NULL; + alter = ft_add_escape(select, ' '); + 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, alter); + 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); + alter ? ft_memdel((void *)&alter) : (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 +** Keypress values for arrows +** 4283163 : Up +** 4348699 : Down +** 4479771 : Left +** 4414235 : Right +*/ + +int c_keypress(t_comp *c, long int key) +{ + t_clst *ptr; + + if (key == 10 || key == 32) + { + ptr = c->lst; + while (!ptr->cursor) + ptr = ptr->next; + c_updater(c, ptr->name); + return (1); + } + else if (key == KP_U || key == KP_D || key == KP_L || key == KP_R) + { + c_arrow(c, key); + return (0); + } + else if (!ft_isprint(key)) + { + c_term_clear(c); + c_clear(data_singleton()); + return (0); + } + return ((c_rematch(c, key)) ? (0) : (1)); +} diff --git a/42sh/src/completion/c_parser.c b/42sh/src/completion/c_parser.c new file mode 100644 index 00000000..7d99ebac --- /dev/null +++ b/42sh/src/completion/c_parser.c @@ -0,0 +1,111 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* c_parser.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: alao +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/09 13:52:07 by alao #+# #+# */ +/* Updated: 2017/03/23 19:05:34 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "completion.h" + +void c_lst_id(t_comp *c) +{ + t_clst *lst; + int i; + + i = 1; + if (!c || !c->lst) + return ; + lst = c->lst; + lst->cursor = 1; + if (!lst) + return ; + while (1) + { + lst->id = i; + lst = lst->next; + ++i; + if (lst == c->lst) + break ; + } +} + +/* +** Add the matching element to the list +*/ + +void c_add_to_lst(t_comp *c, t_clst *node) +{ + t_clst *lst; + + lst = c->lst; + if (c->lst == NULL) + { + c->lst = node; + node->next = node; + node->prev = node; + } + else + { + while (ft_strcmp(lst->name, node->name) < 0) + { + lst = lst->next; + if (lst == c->lst) + break ; + } + lst->prev->next = node; + node->prev = lst->prev; + node->next = lst; + lst->prev = node; + if (lst == c->lst && ft_strcmp(lst->name, node->name) > 0) + c->lst = 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 (!(c->match && ft_strncmp(".", c->match, 1) == 0) && + (ft_strncmp(".", value, 1) == 0 || ft_strncmp("..", value, 2) == 0)) + return (0); + if (!ft_strcmp(value, ".") || !ft_strcmp(value, "..")) + return (0); + if (c->match && ft_strnequ(c->match, value, ft_strlen(c->match)) != 1) + return (0); + if (!(tmp = (t_clst *)ft_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..a8f2eff8 --- /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/03/16 08:50:38 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..430c15d8 --- /dev/null +++ b/42sh/src/completion/c_printer.c @@ -0,0 +1,153 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* c_printer.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: alao +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/10 12:55:39 by alao #+# #+# */ +/* Updated: 2017/03/19 12:14:02 by gwojda ### ########.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", 1) : (0); + lst->type == 10 ? ft_putstr_fd("\e[1;96m", 1) : (0); + lst->cursor ? ft_putstr_fd("\e[0;7m", 1) : (0); + ft_putstr_fd(lst->name, 1); + lst->type == 4 ? ft_putstr_fd("/", 1) : (0); + lst->type == 10 ? ft_putstr_fd("@", 1) : (0); + lst->type != 4 && lst->type != 10 ? ft_putstr_fd(" ", 1) : (0); + while (i++ < (c_sx)) + ft_putstr(" "); + ft_putstr_fd("\e[00m", 1); + 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); +} + +/* +** Return the right pointer in the list from the offset value calculated below. +*/ + +static t_clst *c_rolling_ptr(t_comp *c, int id) +{ + t_clst *ptr; + int i; + + i = (id - 1) * (c->m_size - 1); + ptr = c->lst; + while (i) + { + ptr = ptr->next; + i--; + } + return (ptr); +} + +/* +** Controlling the offset value for the rolling list if the space in the +** terminal is too small to display the whole list. +** +** Controlled value are: +** - x : the column of the element currently selected. +*/ + +static t_clst *c_rolling(t_comp *c) +{ + t_clst *ptr; + int x; + int y; + int id; + + ptr = c->lst; + while (!ptr->cursor) + ptr = ptr->next; + x = 1; + while ((x * c->c_line) < ptr->id) + x++; + id = ((x == 1) ? ptr->id : (ptr->id - ((x - 1) * c->c_line))); + y = 1; + while ((y * (c->m_size - 1)) < id) + y++; + c->pos_x = id; + c->pos_y = y; + if (y > 1) + return (c_rolling_ptr(c, y)); + return (c->lst); +} + +/* +** Control the number of time it cycle for LINE +*/ + +void c_printer(t_comp *c) +{ + t_clst *ptr; + int loop; + int max_line; + + loop = c->c_line; + if (!c->c_line) + return ; + max_line = c->c_line - (c->m_size - 1); + ptr = c_rolling(c); + if ((c->pos_y * (c->m_size - 1)) > c->c_line) + max_line = (c->c_line % (c->m_size - 1)); + else + max_line = c->m_size - 1; + while (loop && max_line) + { + c_printer_line(c, ptr, c->c_pline, 1); + loop > 1 ? ft_putstr(tgetstr("do", NULL)) : (0); + ptr = ptr->next; + loop--; + max_line--; + } +} diff --git a/42sh/src/completion/c_sizing.c b/42sh/src/completion/c_sizing.c new file mode 100644 index 00000000..fcdb32be --- /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/03/16 08:09:00 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_pline && (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..da7a0f05 --- /dev/null +++ b/42sh/src/completion/c_terminal.c @@ -0,0 +1,135 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* c_terminal.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: alao +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/10/11 10:44:40 by alao #+# #+# */ +/* Updated: 2017/03/22 12:14:53 by alao ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "completion.h" + +/* +** Clear the screen and restore cursor position. +** +** First thing is the move the cursor down (do), clear the terminal (cd), back +** up (up) and then move back in position. +*/ + +void c_term_clear(t_comp *c) +{ + int i; + int lcmd; + t_data *s; + + s = data_singleton(); + ft_putstr(tgetstr("do", NULL)); + ft_putstr(tgetstr("cd", NULL)); + ft_putstr(tgetstr("up", NULL)); + i = 0; + lcmd = (c->rcmd) ? ft_nb_last_line(s->line.input, s->line.pos) : 0; + while (i < lcmd) + { + ft_putstr(tgetstr("nd", NULL)); + i++; + } +} + +/* +** Restore cursor position. +** +** Move the cursor up as needed (up) then to the beginning of the line (cr). +** The value check if the current print is a rolling list (terminal too small to +** print the whole list at once). If so, m_size is used or c_line. +** The cursor is then moved to the right (nd) by restore the position. +*/ + +void c_term_mv_back(t_comp *c) +{ + int i; + int lcmd; + int value; + t_data *s; + + s = data_singleton(); + i = 0; + if (c->c_line > c->win_y) + value = c->m_size; + else + value = c->c_line; + while (i != value) + { + ft_putstr(tgetstr("up", NULL)); + i++; + } + ft_putstr(tgetstr("cr", NULL)); + i = 0; + lcmd = (c->rcmd) ? ft_nb_last_line(s->line.input, s->line.pos) : 0; + while (i < lcmd) + { + ft_putstr(tgetstr("nd", NULL)); + i++; + } +} + +/* +** Make room for the list. +** +** Move the cursor down as needed (do) and clear them (cd). +** The value check if the current print is a rolling list (terminal too small to +** print the whole list at once). If so, m_size is used or c_line. +** The cursor is then moved back up to the line just below where it was to begin +** printing the list. +*/ + +void c_term_mv_down(t_comp *c) +{ + int i; + int value; + + i = 0; + if (c->c_line > c->win_y) + value = c->m_size; + else + value = c->c_line; + while (i < value) + { + ft_putstr(tgetstr("do", NULL)); + ft_putstr(tgetstr("cd", NULL)); + i++; + } + i = 0; + if (c->c_line > c->win_y) + value = c->m_size - 1; + else + value = c->c_line - 1; + while (value >= 0 && i != value) + { + ft_putstr(tgetstr("up", NULL)); + i++; + } +} + +/* +** Retrieve new terminal size. +** +** If the terminal has changed in size, the function will refresh these values +** and clear the previous print list. +*/ + +int c_term_resize(t_comp *c) +{ + struct winsize win; + + ioctl(0, TIOCGWINSZ, &win); + if ((win.ws_col == c->win_x) && (win.ws_row == c->win_y)) + return (0); + c->win_x = win.ws_col; + c->win_y = win.ws_row; + c_sizing(c); + c_term_clear(c); + return (0); +} diff --git a/42sh/src/completion/completion.c b/42sh/src/completion/completion.c new file mode 100644 index 00000000..4463a9ad --- /dev/null +++ b/42sh/src/completion/completion.c @@ -0,0 +1,129 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* completion.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: alao +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/09/20 14:50:33 by alao #+# #+# */ +/* Updated: 2017/03/27 22:28:20 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "completion.h" + +/* +** Function to select the next or previous item in the list if it has already +** been created and if the key pressed is tab. +*/ + +static void c_mv_tab(t_comp *c, int next) +{ + t_clst *ptr; + + ptr = c->lst; + while (!ptr->cursor) + ptr = ptr->next; + ptr->cursor = 0; + if (next) + ptr->next->cursor = 1; + else + ptr->prev->cursor = 1; +} + +/* +** Once the completion has been processed, this is the return point. +** The three condition are as follow: +** - If the completion list is empty (NULL), the screen is cleared and (1) is +** returned. +** - If the list contain only one element, c_updater() is called to update the +** string in the struct data then (1) is returned. +** - If the list contain multiple element that mean the completion is not yet +** finished so the c_term_mv_down() drop the terminal to make room for the +** list to be printed using c_printer() and the position is restored by +** calling c_term_mv_back(). (0) s returned because the command doesn't need +** an update to be done. +** +** RETURN VALUE : +** If the function return (1), the line edition module will update the command. +*/ + +int c_dispatcher(t_data *s) +{ + if (s->comp && s->comp->lst == NULL) + { + c_clear(s); + return (1); + } + else if (s->comp && s->comp->lst == s->comp->lst->next) + { + c_updater(s->comp, s->comp->lst->name); + return (1); + } + 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. +** +** The autocompletion module work like the one found in ZSH. Meaning you can +** select the element in a list and complet the command. You can also move in +** it using arrows. It can rematch and update the list of choice with a new +** input from the user. The globbing is also supported. It will also complete +** path (adding /) and solve dots path. +** The completion module work for relative, absolute path and binary from the +** PATH. The env completion is also supported ($[tab]). +** +** The module start by checking if a globbing should be done using +** c_glob_matching(). If so, (1) is returned which trigger an update. +** If the completion structure (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, the first +** thing done is checking if the terminal have been resized between call to +** update the corresponding var. Then 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_keypress() +** is called to process the new key. +** +** 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; + int pos; + + s = data_singleton(); + pos = s->line.pos; + if (c_glob_matching()) + return (1); + if (s->comp == NULL) + { + if (!pos || (s->line.input[pos] != ' ' && s->line.input[pos] != '\0')) + return (0); + c_init(s, keypress); + if (s->comp == NULL) + return (1); + } + else + { + c_term_resize(s->comp); + if (keypress == KP_T || keypress == KP_TS) + keypress == KP_T ? c_mv_tab(s->comp, 1) : c_mv_tab(s->comp, 0); + else if (c_keypress(s->comp, keypress)) + return (1); + } + return (c_dispatcher(s)); +} diff --git a/42sh/src/exec/ast_free.c b/42sh/src/exec/ast_free.c new file mode 100644 index 00000000..ec5599be --- /dev/null +++ b/42sh/src/exec/ast_free.c @@ -0,0 +1,24 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ast_free.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/05 11:50:51 by jhalford #+# #+# */ +/* Updated: 2017/03/22 21:50:11 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void ast_free(void *data, size_t content_size) +{ + t_astnode *node; + + (void)content_size; + node = data; + ft_ld_clear(&node->data.cmd.token, &ft_tabdel); + ft_lstdel(&node->data.cmd.redir, &redir_free); + free(node); +} diff --git a/42sh/src/exec/bad_fd.c b/42sh/src/exec/bad_fd.c new file mode 100644 index 00000000..4b86b0ae --- /dev/null +++ b/42sh/src/exec/bad_fd.c @@ -0,0 +1,19 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* bad_fd.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/06 22:32:43 by jhalford #+# #+# */ +/* Updated: 2017/03/21 16:24:33 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int bad_fd(int fd) +{ + SH_ERR("%i: Bad file descriptor", fd); + return (1); +} diff --git a/42sh/src/exec/exec_ampersand.c b/42sh/src/exec/exec_ampersand.c new file mode 100644 index 00000000..74a260b2 --- /dev/null +++ b/42sh/src/exec/exec_ampersand.c @@ -0,0 +1,28 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* exec_ampersand.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/10 16:01:30 by jhalford #+# #+# */ +/* Updated: 2017/03/16 18:37:56 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int exec_ampersand(t_btree **ast) +{ + t_exec *exec; + + if (!SH_HAS_JOBC(data_singleton()->opts)) + return (exec_semi(ast)); + exec = &data_singleton()->exec; + push(&exec->op_stack, TK_AMP); + ft_exec(&(*ast)->left); + exec->attrs &= ~EXEC_AOL_MASK; + exec->job.attrs &= ~JOB_BG; + ft_exec(&(*ast)->right); + return (0); +} diff --git a/42sh/src/exec/exec_and_if.c b/42sh/src/exec/exec_and_if.c new file mode 100644 index 00000000..d1b714ac --- /dev/null +++ b/42sh/src/exec/exec_and_if.c @@ -0,0 +1,26 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* exec_and_if.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/30 20:52:28 by jhalford #+# #+# */ +/* Updated: 2017/03/20 15:40:02 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int exec_and_if(t_btree **ast) +{ + t_exec *exec; + + exec = &data_singleton()->exec; + push(&exec->op_stack, TK_AND_IF); + ft_exec(&(*ast)->left); + exec->attrs &= ~EXEC_OR_IF; + exec->attrs |= EXEC_AND_IF; + ft_exec(&(*ast)->right); + return (0); +} diff --git a/42sh/src/exec/exec_bang.c b/42sh/src/exec/exec_bang.c new file mode 100644 index 00000000..cce5d557 --- /dev/null +++ b/42sh/src/exec/exec_bang.c @@ -0,0 +1,25 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* exec_bang.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ariard +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/10 14:46:27 by ariard #+# #+# */ +/* Updated: 2017/03/20 15:41:04 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int exec_bang(t_btree **ast) +{ + t_exec *exec; + + exec = &data_singleton()->exec; + push(&exec->op_stack, TK_BANG); + ft_exec(&(*ast)->left); + ft_exec(&(*ast)->right); + set_exitstatus(ft_atoi(ft_getenv(data_singleton()->env, "?")) ? 0 : 1, 1); + return (0); +} diff --git a/42sh/src/exec/exec_case_branch.c b/42sh/src/exec/exec_case_branch.c new file mode 100644 index 00000000..3991cb23 --- /dev/null +++ b/42sh/src/exec/exec_case_branch.c @@ -0,0 +1,35 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* exec_case_branch.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/07 20:33:45 by wescande #+# #+# */ +/* Updated: 2017/03/29 12:22:56 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int exec_case_branch(t_btree **ast) +{ + t_astnode *node; + char **av; + t_exec *exec; + + exec = &data_singleton()->exec; + if (EXEC_IS_CASE_BRANCH(exec->attrs) || !exec->case_pattern + || !*exec->case_pattern) + return (0); + node = (*ast)->item; + av = token_to_argv(node->data.cmd.token, 1); + if (av && (ft_strcmp(av[0], ((char **)exec->case_pattern)[0]) == 0)) + { + exec->attrs |= EXEC_CASE_BRANCH; + ft_tabdel(&exec->case_pattern); + ft_exec(&(*ast)->right); + } + ft_tabdel(&av); + return (0); +} diff --git a/42sh/src/exec/exec_destroy.c b/42sh/src/exec/exec_destroy.c new file mode 100644 index 00000000..c01bae48 --- /dev/null +++ b/42sh/src/exec/exec_destroy.c @@ -0,0 +1,23 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* exec_destroy.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/27 03:09:58 by jhalford #+# #+# */ +/* Updated: 2017/03/27 15:56:47 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int exec_destroy(t_exec *exec) +{ + if (!exec) + return (1); + ft_lstdel(&exec->op_stack, ft_lst_cfree); + exec->attrs = 0; + exec->fdin = STDIN; + return (0); +} diff --git a/42sh/src/exec/exec_elif.c b/42sh/src/exec/exec_elif.c new file mode 100644 index 00000000..f3742225 --- /dev/null +++ b/42sh/src/exec/exec_elif.c @@ -0,0 +1,29 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* exec_elif.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ariard +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/06 18:08:53 by ariard #+# #+# */ +/* Updated: 2017/03/15 02:04:57 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int exec_elif(t_btree **ast) +{ + t_exec *exec; + + exec = &data_singleton()->exec; + if (EXEC_IS_IF_BRANCH(exec->attrs)) + return (0); + ft_exec(&(*ast)->left); + if (ft_strcmp(ft_getenv(data_singleton()->env, "?"), "0") == 0) + { + exec->attrs |= EXEC_IF_BRANCH; + ft_exec(&(*ast)->right); + } + return (0); +} diff --git a/42sh/src/exec/exec_else.c b/42sh/src/exec/exec_else.c new file mode 100644 index 00000000..72e132b1 --- /dev/null +++ b/42sh/src/exec/exec_else.c @@ -0,0 +1,25 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* exec_else.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ariard +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/06 18:55:07 by ariard #+# #+# */ +/* Updated: 2017/03/04 18:06:55 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int exec_else(t_btree **ast) +{ + t_exec *exec; + + exec = &data_singleton()->exec; + if (EXEC_IS_IF_BRANCH(exec->attrs)) + return (0); + exec->attrs |= EXEC_IF_BRANCH; + ft_exec(&(*ast)->left); + return (0); +} diff --git a/42sh/src/exec/exec_func.c b/42sh/src/exec/exec_func.c new file mode 100644 index 00000000..a7645931 --- /dev/null +++ b/42sh/src/exec/exec_func.c @@ -0,0 +1,56 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* exec_func.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ariard +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/23 16:25:23 by ariard #+# #+# */ +/* Updated: 2017/03/24 17:22:12 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +t_list *is_already_func(t_btree **new) +{ + t_list *tmp; + t_btree **ast; + char **new_name; + char **old_name; + int ret; + + tmp = data_singleton()->lst_func; + new_name = token_to_argv(((t_astnode *)(*new)->item)->data.cmd.token, 1); + ret = 1; + while (tmp && ret) + { + if ((ast = tmp->content) && !*ast) + break ; + old_name = token_to_argv(((t_astnode *) + (*ast)->item)->data.cmd.token, 1); + ret = (new_name && new_name[0] && old_name && old_name[0] + && !ft_strcmp(new_name[0], old_name[0])) ? 0 : 1; + ft_tabdel(&old_name); + tmp = (ret) ? tmp->next : tmp; + } + ft_tabdel(&new_name); + if (!ret) + return (tmp); + return (NULL); +} + +int exec_func(t_btree **ast) +{ + t_btree *func_ast; + t_list *old_func; + + func_ast = btree_map(*ast, &node_copy); + if ((old_func = is_already_func(&func_ast))) + { + ft_lst_delif(&data_singleton()->lst_func, + old_func->content, &ft_addrcmp, &tree_func_free); + } + ft_lsteadd(&data_singleton()->lst_func, ft_lstnew(&func_ast, sizeof(*ast))); + return (0); +} diff --git a/42sh/src/exec/exec_init.c b/42sh/src/exec/exec_init.c new file mode 100644 index 00000000..4491a770 --- /dev/null +++ b/42sh/src/exec/exec_init.c @@ -0,0 +1,32 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* exec_init.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/26 21:28:09 by jhalford #+# #+# */ +/* Updated: 2017/03/27 19:46:42 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int job_init(t_job *job) +{ + job->id = 0; + job->pgid = 0; + job->attrs = 0; + job->first_process = NULL; + tcgetattr(STDIN, &job->tmodes); + return (0); +} + +int exec_init(t_exec *exec) +{ + job_init(&exec->job); + exec->attrs = 0; + exec->fdin = STDIN; + exec->op_stack = NULL; + return (0); +} diff --git a/42sh/src/exec/exec_leaf.c b/42sh/src/exec/exec_leaf.c new file mode 100644 index 00000000..88ac6da0 --- /dev/null +++ b/42sh/src/exec/exec_leaf.c @@ -0,0 +1,54 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* exec_leaf.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/07 15:47:30 by wescande #+# #+# */ +/* Updated: 2017/03/24 19:24:44 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +t_process_map g_process_map[] = +{ + {PROCESS_FUNCTION, plaunch_function, pprint_function, pfree_func}, + {PROCESS_BUILTIN, plaunch_builtin, pprint_cmd, pfree_cmd}, + {PROCESS_FILE, plaunch_file, pprint_cmd, pfree_cmd}, + {PROCESS_SUBSHELL, plaunch_subshell, pprint_subshell, pfree_subshell}, + {PROCESS_BRACE, plaunch_brace, pprint_brace, pfree_subshell}, + {PROCESS_WHILE, plaunch_while, pprint_while, pfree_cond}, + {PROCESS_UNTIL, plaunch_until, pprint_until, pfree_cond}, + {PROCESS_IF, plaunch_if, pprint_if, pfree_subshell}, + {PROCESS_FOR, plaunch_for, pprint_for, pfree_list}, + {PROCESS_CASE, plaunch_case, pprint_case, pfree_list}, + {PROCESS_EMPTY, plaunch_empty, NULL, NULL}, +}; + +int exec_leaf(t_btree **ast) +{ + t_process p; + t_job *job; + + job = &data_singleton()->exec.job; + if (process_set(&p, *ast)) + return (1); + if (p.type >= PROCESS_MAX) + return (1); + p.map = g_process_map[p.type]; + if (process_launch(&p)) + { + job_addprocess(&p); + if (IS_PIPEEND(p)) + { + if (JOB_IS_FG(job->attrs)) + put_job_in_foreground(job, 0); + else + job_notify_new(job->id); + job->pgid = 0; + } + } + return (0); +} diff --git a/42sh/src/exec/exec_or_if.c b/42sh/src/exec/exec_or_if.c new file mode 100644 index 00000000..5885eb6d --- /dev/null +++ b/42sh/src/exec/exec_or_if.c @@ -0,0 +1,26 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* exec_or_if.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/30 21:06:17 by jhalford #+# #+# */ +/* Updated: 2017/03/20 15:40:15 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int exec_or_if(t_btree **ast) +{ + t_exec *exec; + + exec = &data_singleton()->exec; + push(&exec->op_stack, TK_OR_IF); + ft_exec(&(*ast)->left); + exec->attrs &= ~EXEC_AND_IF; + exec->attrs = EXEC_OR_IF; + ft_exec(&(*ast)->right); + return (0); +} diff --git a/42sh/src/exec/exec_pipe.c b/42sh/src/exec/exec_pipe.c new file mode 100644 index 00000000..0c015741 --- /dev/null +++ b/42sh/src/exec/exec_pipe.c @@ -0,0 +1,24 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* exec_pipe.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/27 21:13:23 by jhalford #+# #+# */ +/* Updated: 2017/03/20 15:42:40 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int exec_pipe(t_btree **ast) +{ + t_exec *exec; + + exec = &data_singleton()->exec; + push(&exec->op_stack, TK_PIPE); + ft_exec(&(*ast)->left); + ft_exec(&(*ast)->right); + return (0); +} diff --git a/42sh/src/exec/exec_semi.c b/42sh/src/exec/exec_semi.c new file mode 100644 index 00000000..25a34a94 --- /dev/null +++ b/42sh/src/exec/exec_semi.c @@ -0,0 +1,25 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* exec_semi.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/30 20:52:05 by jhalford #+# #+# */ +/* Updated: 2017/03/15 15:55:43 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int exec_semi(t_btree **ast) +{ + t_exec *exec; + + exec = &data_singleton()->exec; + push(&exec->op_stack, TK_SEMI); + ft_exec(&(*ast)->left); + exec->attrs &= ~EXEC_AOL_MASK; + ft_exec(&(*ast)->right); + return (0); +} diff --git a/42sh/src/exec/exec_var.c b/42sh/src/exec/exec_var.c new file mode 100644 index 00000000..93cd7a02 --- /dev/null +++ b/42sh/src/exec/exec_var.c @@ -0,0 +1,35 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* exec_var.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ariard +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/07 11:12:05 by ariard #+# #+# */ +/* Updated: 2017/03/24 19:44:30 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int exec_var(t_btree **ast) +{ + t_astnode *node; + char **av; + char *var; + char *value; + char *equal; + + node = (*ast)->item; + pop(&data_singleton()->exec.op_stack); + if (!(av = token_to_argv(node->data.cmd.token, 1))) + return (0); + var = av[0]; + if ((equal = ft_strchr(av[0], '='))) + *equal = 0; + value = equal ? equal + 1 : NULL; + builtin_setenv("internal", (char*[]){"local", var, value, 0}, NULL); + ft_sstrfree(av); + ft_exec(&(*ast)->right); + 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..67a1c7f1 --- /dev/null +++ b/42sh/src/exec/fd_is_valid.c @@ -0,0 +1,24 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* fd_is_valid.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/03 13:46:40 by jhalford #+# #+# */ +/* Updated: 2017/03/27 00:51:02 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int fd_is_valid(int fd, int has_mode) +{ + int fd_flags; + int fd_modes; + + fd_modes = fcntl(fd, F_GETFL); + fd_flags = fcntl(fd, F_GETFD); + return ((fd_flags != -1 || errno != EBADF) + && (has_mode == -1 || fd_modes & has_mode)); +} diff --git a/42sh/src/exec/ft_exec.c b/42sh/src/exec/ft_exec.c new file mode 100644 index 00000000..b88b6acc --- /dev/null +++ b/42sh/src/exec/ft_exec.c @@ -0,0 +1,56 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_exec.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/27 20:30:32 by jhalford #+# #+# */ +/* Updated: 2017/03/23 16:25:01 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +t_itof g_execmap[] = +{ + {TK_NEWLINE, &exec_semi}, + {TK_SEMI, &exec_semi}, + {TK_AMP, &exec_ampersand}, + {TK_AND_IF, &exec_and_if}, + {TK_OR_IF, &exec_or_if}, + {TK_PIPE, &exec_pipe}, + {TK_WHILE, &exec_leaf}, + {TK_IF, &exec_leaf}, + {TK_ELIF, &exec_elif}, + {TK_ELSE, &exec_else}, + {TK_UNTIL, &exec_leaf}, + {TK_FOR, &exec_leaf}, + {TK_CASE, &exec_leaf}, + {TK_PAREN_OPEN, &exec_case_branch}, + {TK_ASSIGNMENT_WORD, &exec_var}, + {SUBSHELL, &exec_leaf}, + {TK_LBRACE, &exec_leaf}, + {TK_BANG, &exec_bang}, + {FNAME, &exec_func}, + {CMD, &exec_leaf}, + {0, 0}, +}; + +int ft_exec(t_btree **ast) +{ + t_astnode *item; + int i; + + i = 0; + if (!*ast) + return (0); + item = (*ast)->item; + while (g_execmap[i].id) + { + if (item->type == g_execmap[i].id) + return ((*g_execmap[i].f)(ast)); + i++; + } + return (0); +} diff --git a/42sh/src/exec/ft_findexec.c b/42sh/src/exec/ft_findexec.c new file mode 100644 index 00000000..813992da --- /dev/null +++ b/42sh/src/exec/ft_findexec.c @@ -0,0 +1,53 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_findexec.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/03 13:37:49 by jhalford #+# #+# */ +/* Updated: 2017/03/21 17:40:28 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static char *create_path(char *path, char *name, char **spath) +{ + char *execpath; + + if (path[ft_strlen(path)] != '/') + execpath = ft_str3join(path, "/", name); + else + execpath = ft_strjoin(path, name); + ft_sstrfree(spath); + return (execpath); +} + +char *ft_findexec(char *path, char *file) +{ + int i; + DIR *dir; + char **spath; + struct dirent *dirent; + char *execpath; + + i = -1; + spath = ft_strsplit(path, ':'); + while (spath && spath[++i]) + { + if (!(dir = opendir(spath[i]))) + continue ; + while ((dirent = readdir(dir))) + { + if (ft_strcmp(dirent->d_name, file)) + continue ; + execpath = create_path(spath[i], dirent->d_name, spath); + closedir(dir); + return (execpath); + } + closedir(dir); + } + ft_sstrfree(spath); + return (NULL); +} diff --git a/42sh/src/exec/is_function.c b/42sh/src/exec/is_function.c new file mode 100644 index 00000000..d7bdc94a --- /dev/null +++ b/42sh/src/exec/is_function.c @@ -0,0 +1,38 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* is_function.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/08 02:45:15 by wescande #+# #+# */ +/* Updated: 2017/03/21 21:17:59 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +t_btree *is_function(t_process *p) +{ + t_list *tmp; + t_btree **ast; + char **av; + int ret; + + tmp = data_singleton()->lst_func; + ret = 1; + while (tmp && ret) + { + ast = tmp->content; + if (!*ast) + return (NULL); + av = token_to_argv(((t_astnode *)(*ast)->item)->data.cmd.token, 1); + if (av && av[0] && !ft_strcmp(av[0], p->data.cmd.av[0])) + ret = 0; + ft_tabdel(&av); + tmp = tmp->next; + } + if (!ret) + return (btree_map((*ast)->right, node_copy)); + return (NULL); +} diff --git a/42sh/src/exec/mark_process_status.c b/42sh/src/exec/mark_process_status.c new file mode 100644 index 00000000..d31a996a --- /dev/null +++ b/42sh/src/exec/mark_process_status.c @@ -0,0 +1,40 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* process_mark_status.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/12 12:41:11 by jhalford #+# #+# */ +/* Updated: 2017/03/27 03:08:10 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int mark_process_status(pid_t pid, int status) +{ + t_list *plist; + t_process *p; + int signo; + + if ((plist = job_getprocess(pid))) + { + p = plist->content; + p->status = status; + if (WIFSTOPPED(status)) + p->state = PROCESS_SUSPENDED; + else + { + p->state = PROCESS_COMPLETED; + if (WIFSIGNALED(status) && (signo = WTERMSIG(status))) + { + if (signo != SIGPIPE && signo != SIGINT) + ft_dprintf(2, "%s\n", strsignal(signo)); + } + } + return (0); + } + SH_ERR("No child process %i", pid); + return (1); +} diff --git a/42sh/src/exec/node_copy.c b/42sh/src/exec/node_copy.c new file mode 100644 index 00000000..a192715a --- /dev/null +++ b/42sh/src/exec/node_copy.c @@ -0,0 +1,31 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* node_copy.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/08 03:38:36 by wescande #+# #+# */ +/* Updated: 2017/03/23 16:35:19 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void *node_copy(void *data) +{ + t_astnode *new; + t_astnode *old; + + if (!data) + return (NULL); + old = data; + new = (t_astnode *)ft_memalloc(sizeof(t_astnode)); + new->nest = old->nest; + new->full = old->full; + new->type = old->type; + new->pattern = old->pattern; + new->data.cmd.redir = ft_lstmap(old->data.cmd.redir, &redir_copy); + new->data.cmd.token = ft_ld_copy(old->data.cmd.token, &tab_esc_copy); + return (new); +} diff --git a/42sh/src/exec/pfree_cmd.c b/42sh/src/exec/pfree_cmd.c new file mode 100644 index 00000000..58ebe736 --- /dev/null +++ b/42sh/src/exec/pfree_cmd.c @@ -0,0 +1,22 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* pfree_cmd.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/08 00:58:02 by wescande #+# #+# */ +/* Updated: 2017/03/22 23:17:54 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int pfree_cmd(t_process *p) +{ + ft_strdel(&p->data.cmd.path); + ft_sstrfree(p->data.cmd.av); + p->data.cmd.execf = NULL; + ft_memdel((void**)&p->data.cmd.stat); + return (0); +} diff --git a/42sh/src/exec/pfree_cond.c b/42sh/src/exec/pfree_cond.c new file mode 100644 index 00000000..6bbb757d --- /dev/null +++ b/42sh/src/exec/pfree_cond.c @@ -0,0 +1,21 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* pfree_cond.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/08 02:26:31 by wescande #+# #+# */ +/* Updated: 2017/03/20 19:13:40 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int pfree_cond(t_process *p) +{ + btree_del(&p->data.d_while.condition, &ast_free); + btree_del(&p->data.d_while.content, &ast_free); + btree_del(&p->data.d_while.condition, &ast_free); + return (0); +} diff --git a/42sh/src/exec/pfree_func.c b/42sh/src/exec/pfree_func.c new file mode 100644 index 00000000..b8a467b7 --- /dev/null +++ b/42sh/src/exec/pfree_func.c @@ -0,0 +1,19 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* pfree_func.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ariard +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/21 20:18:34 by ariard #+# #+# */ +/* Updated: 2017/03/22 19:25:38 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int pfree_func(t_process *p) +{ + btree_del(&p->data.function.content, &ast_free); + return (0); +} diff --git a/42sh/src/exec/pfree_list.c b/42sh/src/exec/pfree_list.c new file mode 100644 index 00000000..cf7856ce --- /dev/null +++ b/42sh/src/exec/pfree_list.c @@ -0,0 +1,20 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* pfree_list.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/08 02:37:04 by wescande #+# #+# */ +/* Updated: 2017/03/23 06:05:22 by wescande ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int pfree_list(t_process *p) +{ + ft_ld_clear(&p->data.d_for.token, &ft_tabdel); + btree_del(&p->data.d_for.content, &ast_free); + return (0); +} diff --git a/42sh/src/exec/pfree_subshell.c b/42sh/src/exec/pfree_subshell.c new file mode 100644 index 00000000..52a9c44f --- /dev/null +++ b/42sh/src/exec/pfree_subshell.c @@ -0,0 +1,19 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* pfree_subshell.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/08 02:38:12 by wescande #+# #+# */ +/* Updated: 2017/03/21 20:03:21 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int pfree_subshell(t_process *p) +{ + btree_del(&p->data.subshell.content, &ast_free); + return (0); +} diff --git a/42sh/src/exec/plaunch_brace.c b/42sh/src/exec/plaunch_brace.c new file mode 100644 index 00000000..69fe397d --- /dev/null +++ b/42sh/src/exec/plaunch_brace.c @@ -0,0 +1,19 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* plaunch_brace.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/13 19:09:30 by jhalford #+# #+# */ +/* Updated: 2017/03/21 00:52:20 by wescande ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int plaunch_brace(t_process *p) +{ + ft_exec(&p->data.brace.content); + return (0); +} diff --git a/42sh/src/exec/plaunch_builtin.c b/42sh/src/exec/plaunch_builtin.c new file mode 100644 index 00000000..1efa4ae8 --- /dev/null +++ b/42sh/src/exec/plaunch_builtin.c @@ -0,0 +1,22 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* plaunch_builtin.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/07 15:48:24 by jhalford #+# #+# */ +/* Updated: 2017/03/27 16:03:21 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int plaunch_builtin(t_process *p) +{ + set_exitstatus((*p->data.cmd.execf)( + p->data.cmd.path, + p->data.cmd.av, + data_singleton()->env), 1); + return (0); +} diff --git a/42sh/src/exec/plaunch_case.c b/42sh/src/exec/plaunch_case.c new file mode 100644 index 00000000..6c96e76e --- /dev/null +++ b/42sh/src/exec/plaunch_case.c @@ -0,0 +1,25 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* plaunch_case.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/07 19:02:23 by wescande #+# #+# */ +/* Updated: 2017/03/27 15:06:42 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int plaunch_case(t_process *p) +{ + t_exec *exec; + + exec = &data_singleton()->exec; + exec->attrs &= ~EXEC_CASE_BRANCH; + exec->case_pattern = token_to_argv(p->data.d_case.token, 1); + ft_exec(&p->data.d_case.content); + ft_tabdel(&exec->case_pattern); + return (0); +} diff --git a/42sh/src/exec/plaunch_empty.c b/42sh/src/exec/plaunch_empty.c new file mode 100644 index 00000000..c550c3c8 --- /dev/null +++ b/42sh/src/exec/plaunch_empty.c @@ -0,0 +1,19 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* plaunch_empty.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/13 17:26:01 by jhalford #+# #+# */ +/* Updated: 2017/03/20 15:50:16 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int plaunch_empty(t_process *p) +{ + (void)p; + return (0); +} diff --git a/42sh/src/exec/plaunch_file.c b/42sh/src/exec/plaunch_file.c new file mode 100644 index 00000000..474bb30d --- /dev/null +++ b/42sh/src/exec/plaunch_file.c @@ -0,0 +1,37 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* plaunch_file.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/07 14:53:31 by jhalford #+# #+# */ +/* Updated: 2017/03/27 16:46:06 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static void error_launch(char *error_ori, char *error_type, int error_code) +{ + SH_ERR("%s%s", error_ori, error_type); + exit(error_code); +} + +int plaunch_file(t_process *p) +{ + if (!p->data.cmd.path) + error_launch("command not found: ", p->data.cmd.av[0], 127); + else if (access(p->data.cmd.path, F_OK) == -1) + error_launch(p->data.cmd.av[0], ": no such file or directory", 127); + else if (S_ISDIR(p->data.cmd.stat->st_mode)) + error_launch(p->data.cmd.av[0], ": is a directory", 126); + else if (access(p->data.cmd.path, X_OK) == -1) + error_launch("permission denied: ", p->data.cmd.av[0], 126); + shell_fds_destroy(); + execve(p->data.cmd.path, + p->data.cmd.av, + data_singleton()->env); + error_launch("internal execve error on ", p->data.cmd.av[0], 42); + return (0); +} diff --git a/42sh/src/exec/plaunch_for.c b/42sh/src/exec/plaunch_for.c new file mode 100644 index 00000000..f1f0ad27 --- /dev/null +++ b/42sh/src/exec/plaunch_for.c @@ -0,0 +1,39 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* plaunch_for.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/15 00:49:20 by wescande #+# #+# */ +/* Updated: 2017/03/28 20:29:55 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +#define FORERR_0 ": `%s' not a valid identifier" + +int plaunch_for(t_process *p) +{ + t_ld *temp; + int i; + char **av; + char *var; + + temp = p->data.d_for.token; + var = ((char **)temp->content)[0]; + if (!word_is_assignment(temp->content)) + return (SH_ERR(FORERR_0, var)); + i = 0; + av = token_to_argv(temp, 1); + data_singleton()->exec.job.attrs &= ~JOB_BG; + while (av[++i]) + { + builtin_setenv("setenv", (char*[]){"local", var, av[i], 0}, + NULL); + ft_exec(&p->data.d_for.content); + } + ft_tabdel(&av); + return (1); +} diff --git a/42sh/src/exec/plaunch_function.c b/42sh/src/exec/plaunch_function.c new file mode 100644 index 00000000..d86ba3db --- /dev/null +++ b/42sh/src/exec/plaunch_function.c @@ -0,0 +1,28 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* plaunch_function.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/08 03:23:59 by wescande #+# #+# */ +/* Updated: 2017/03/24 16:53:04 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +#define FUNCERR_0 ":maximum nested function level reached" +#define FUNC_LVL 200 + +int plaunch_function(t_process *p) +{ + static int protection; + + if (protection >= FUNC_LVL) + return (SH_ERR(FUNCERR_0)); + protection++; + ft_exec(&p->data.function.content); + protection--; + return (ft_atoi(ft_getenv(data_singleton()->env, "?"))); +} diff --git a/42sh/src/exec/plaunch_if.c b/42sh/src/exec/plaunch_if.c new file mode 100644 index 00000000..e144a032 --- /dev/null +++ b/42sh/src/exec/plaunch_if.c @@ -0,0 +1,20 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* plaunch_if.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/07 17:26:53 by wescande #+# #+# */ +/* Updated: 2017/03/22 19:23:33 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int plaunch_if(t_process *p) +{ + data_singleton()->exec.attrs &= ~EXEC_IF_BRANCH; + ft_exec(&p->data.d_if.content); + return (0); +} diff --git a/42sh/src/exec/plaunch_subshell.c b/42sh/src/exec/plaunch_subshell.c new file mode 100644 index 00000000..69a0dc8a --- /dev/null +++ b/42sh/src/exec/plaunch_subshell.c @@ -0,0 +1,20 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* plaunch_subshell.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/08 00:11:44 by wescande #+# #+# */ +/* Updated: 2017/03/21 00:52:42 by wescande ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int plaunch_subshell(t_process *p) +{ + ft_exec(&p->data.subshell.content); + exit(ft_atoi(ft_getenv(data_singleton()->env, "?"))); + return (0); +} diff --git a/42sh/src/exec/plaunch_until.c b/42sh/src/exec/plaunch_until.c new file mode 100644 index 00000000..17529fc1 --- /dev/null +++ b/42sh/src/exec/plaunch_until.c @@ -0,0 +1,30 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* plaunch_until.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/07 22:04:42 by wescande #+# #+# */ +/* Updated: 2017/03/28 20:30:19 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int plaunch_until(t_process *p) +{ + int ret; + + ret = 0; + data_singleton()->exec.job.attrs &= ~JOB_BG; + ft_exec(&p->data.d_until.condition); + while (ft_strcmp(ft_getenv(data_singleton()->env, "?"), "0")) + { + ft_exec(&p->data.d_until.content); + ret = ft_atoi(ft_getenv(data_singleton()->env, "?")); + ft_exec(&p->data.d_until.condition); + } + set_exitstatus(ret, 1); + return (0); +} diff --git a/42sh/src/exec/plaunch_while.c b/42sh/src/exec/plaunch_while.c new file mode 100644 index 00000000..9caaa1bd --- /dev/null +++ b/42sh/src/exec/plaunch_while.c @@ -0,0 +1,30 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* plaunch_while.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/07 17:20:53 by wescande #+# #+# */ +/* Updated: 2017/03/28 20:29:54 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int plaunch_while(t_process *p) +{ + int ret; + + ret = 0; + data_singleton()->exec.job.attrs &= ~JOB_BG; + ft_exec(&p->data.d_while.condition); + while (!(ft_strcmp(ft_getenv(data_singleton()->env, "?"), "0"))) + { + ft_exec(&p->data.d_while.content); + ret = ft_atoi(ft_getenv(data_singleton()->env, "?")); + ft_exec(&p->data.d_while.condition); + } + set_exitstatus(ret, 1); + return (0); +} diff --git a/42sh/src/exec/process_launch.c b/42sh/src/exec/process_launch.c new file mode 100644 index 00000000..7f59bd60 --- /dev/null +++ b/42sh/src/exec/process_launch.c @@ -0,0 +1,65 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* process_launch.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/13 22:21:19 by jhalford #+# #+# */ +/* Updated: 2017/03/29 11:03:08 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int process_fork(t_process *p) +{ + pid_t pid; + + if ((pid = fork()) == -1) + exit(SH_ERR("fork(): %s", strerror(errno))); + else if (pid != 0) + return (pid); + if (!p) + return (0); + exec_destroy(&data_singleton()->exec); + jobc_destroy(&data_singleton()->jobc); + if ((pid = 1) && process_redirect(p) == 0) + { + shell_fds_push(); + process_setgroup(p, 0); + process_setsig(); + data_singleton()->opts &= ~(SH_INTERACTIVE | SH_OPTS_JOBC); + pid = p->map.launch(p); + } + shell_fds_destroy(); + exit(pid); +} + +int process_launch(t_process *p) +{ + p->state = PROCESS_RUNNING; + if (!IS_PIPESINGLE(*p) || p->type == PROCESS_FILE + || p->type == PROCESS_SUBSHELL) + { + p->pid = process_fork(p); + process_setgroup(p, p->pid); + if (p->fdin != STDIN) + close(p->fdin); + if (p->fdout != STDOUT) + close(p->fdout); + return (1); + } + if (process_redirect(p)) + set_exitstatus(1, 1); + else + { + shell_fds_push(); + p->map.launch(p); + shell_fds_pop(); + } + shell_fds_reset(); + shell_sig_reset(); + process_free(p, 0); + return (0); +} diff --git a/42sh/src/exec/process_redirect.c b/42sh/src/exec/process_redirect.c new file mode 100644 index 00000000..c9f63252 --- /dev/null +++ b/42sh/src/exec/process_redirect.c @@ -0,0 +1,53 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* process_redirect.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/29 16:04:18 by jhalford #+# #+# */ +/* Updated: 2017/03/24 17:22:18 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +t_itof 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; + if (p->to_close != STDIN) + close(p->to_close); + fd_replace(p->fdin, STDIN); + fd_replace(p->fdout, STDOUT); + while (redirs) + { + redir = redirs->content; + if (redir->n > 9) + return (bad_fd(redir->n)); + i = -1; + while (g_redirmap[++i].id) + if (g_redirmap[i].id == redir->type) + { + if ((g_redirmap[i].f)(redir)) + return (1); + break ; + } + redirs = redirs->next; + } + return (0); +} diff --git a/42sh/src/exec/process_set.c b/42sh/src/exec/process_set.c new file mode 100644 index 00000000..cbb3d11a --- /dev/null +++ b/42sh/src/exec/process_set.c @@ -0,0 +1,72 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* process_set.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/05 14:54:45 by jhalford #+# #+# */ +/* Updated: 2017/03/27 00:10:47 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +t_itof g_setprocessmap[] = +{ + {TK_WHILE, &pset_while}, + {TK_IF, &pset_if}, + {TK_UNTIL, &pset_until}, + {TK_FOR, &pset_for}, + {TK_CASE, &pset_case}, + {SUBSHELL, &pset_subshell}, + {CMD, &pset_cmd}, + {TK_LBRACE, &pset_brace}, + {0, NULL} +}; + +static int process_set_spec(t_process *p, t_btree *ast) +{ + int i; + t_astnode *item; + + if (!ast) + return (0); + item = ast->item; + i = -1; + while (g_setprocessmap[++i].id) + if (item->type == g_setprocessmap[i].id) + { + if (!g_setprocessmap[i].f) + return (1); + return ((*g_setprocessmap[i].f)(p, ast)); + } + return (1); +} + +int process_set(t_process *p, t_btree *ast) +{ + t_exec *exec; + int op; + int fds[2]; + + ft_bzero(p, sizeof(t_process)); + exec = &data_singleton()->exec; + op = pop(&exec->op_stack); + if ((EXEC_IS_AND_IF(exec->attrs) + && ft_strcmp(ft_getenv(data_singleton()->env, "?"), "0") != 0) + || (EXEC_IS_OR_IF(exec->attrs) + && ft_strcmp(ft_getenv(data_singleton()->env, "?"), "0") == 0)) + return (1); + exec->job.attrs |= (op == TK_AMP ? JOB_BG : 0); + p->fdin = exec->fdin; + (op == TK_PIPE) ? pipe(fds) : (0); + p->fdout = (op == TK_PIPE) ? fds[PIPE_WRITE] : STDOUT; + exec->fdin = (op == TK_PIPE) ? fds[PIPE_READ] : STDIN; + p->to_close = exec->fdin; + p->pid = 0; + if (ast) + p->redirs = ft_lstmap( + ((t_astnode *)ast->item)->data.cmd.redir, &redir_copy); + return (process_set_spec(p, ast)); +} diff --git a/42sh/src/exec/process_setgroup.c b/42sh/src/exec/process_setgroup.c new file mode 100644 index 00000000..0f39a343 --- /dev/null +++ b/42sh/src/exec/process_setgroup.c @@ -0,0 +1,30 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* process_setgroup.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/13 17:48:10 by jhalford #+# #+# */ +/* Updated: 2017/03/23 06:36:05 by wescande ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int process_setgroup(t_process *p, pid_t pid) +{ + t_job *j; + t_data *data; + + (void)p; + data = data_singleton(); + j = &data->exec.job; + if (!SH_IS_INTERACTIVE(data_singleton()->opts)) + return (0); + if (setpgid(pid, j->pgid) == -1) + SH_ERR("setpgid(): %s", strerror(errno)); + if (pid == 0 && JOB_IS_FG(j->attrs)) + tcsetpgrp(STDIN, j->pgid); + return (0); +} diff --git a/42sh/src/exec/process_setsig.c b/42sh/src/exec/process_setsig.c new file mode 100644 index 00000000..126c0267 --- /dev/null +++ b/42sh/src/exec/process_setsig.c @@ -0,0 +1,23 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* process_setsig.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/11 14:08:35 by jhalford #+# #+# */ +/* Updated: 2017/03/22 16:05:27 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void process_setsig(void) +{ + signal(SIGINT, SIG_DFL); + signal(SIGQUIT, SIG_DFL); + signal(SIGTSTP, SIG_DFL); + signal(SIGTTIN, SIG_DFL); + signal(SIGTTOU, SIG_DFL); + signal(SIGCHLD, SIG_DFL); +} diff --git a/42sh/src/exec/pset_brace.c b/42sh/src/exec/pset_brace.c new file mode 100644 index 00000000..226297bb --- /dev/null +++ b/42sh/src/exec/pset_brace.c @@ -0,0 +1,20 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* pset_brace.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/13 19:07:34 by jhalford #+# #+# */ +/* Updated: 2017/03/20 15:58:50 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int pset_brace(t_process *p, t_btree *ast) +{ + p->data.subshell.content = btree_map(ast->right, &node_copy); + p->type = PROCESS_BRACE; + return (0); +} diff --git a/42sh/src/exec/pset_case.c b/42sh/src/exec/pset_case.c new file mode 100644 index 00000000..20602607 --- /dev/null +++ b/42sh/src/exec/pset_case.c @@ -0,0 +1,22 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* pset_case.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/07 20:36:04 by wescande #+# #+# */ +/* Updated: 2017/03/27 03:42:29 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int pset_case(t_process *p, t_btree *ast) +{ + p->data.d_case.token = ft_ld_copy(((t_astnode *)ast->item)->data.cmd.token, + tab_esc_copy); + p->data.d_case.content = btree_map(ast->right, &node_copy); + p->type = PROCESS_CASE; + return (0); +} diff --git a/42sh/src/exec/pset_cmd.c b/42sh/src/exec/pset_cmd.c new file mode 100644 index 00000000..fc1515f5 --- /dev/null +++ b/42sh/src/exec/pset_cmd.c @@ -0,0 +1,41 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* pset_cmd.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/20 12:41:54 by jhalford #+# #+# */ +/* Updated: 2017/03/23 14:48:58 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int pset_cmd(t_process *p, t_btree *ast) +{ + t_btree *func; + + if (ast && !(p->data.cmd.av = + token_to_argv(((t_astnode *)ast->item)->data.cmd.token, 1))) + return ((p->type = PROCESS_EMPTY) ? 0 : 0); + if ((func = is_function(p))) + { + ft_tabdel(&p->data.cmd.av); + p->data.function.content = func; + p->type = PROCESS_FUNCTION; + } + else if ((p->data.cmd.execf = is_builtin(p))) + p->type = PROCESS_BUILTIN; + else if ((p->type = PROCESS_FILE)) + { + p->data.cmd.stat = ft_memalloc(sizeof(struct stat)); + p->data.cmd.execf = &execve; + p->data.cmd.path = ft_strchr(p->data.cmd.av[0], '/') ? + ft_strdup(p->data.cmd.av[0]) : ft_hash(p->data.cmd.av[0]); + if (p->data.cmd.path && !access(p->data.cmd.path, F_OK) + && stat(p->data.cmd.path, p->data.cmd.stat) == -1) + return (-1); + } + return (0); +} diff --git a/42sh/src/exec/pset_for.c b/42sh/src/exec/pset_for.c new file mode 100644 index 00000000..edca1f97 --- /dev/null +++ b/42sh/src/exec/pset_for.c @@ -0,0 +1,22 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* pset_for.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/07 19:38:05 by wescande #+# #+# */ +/* Updated: 2017/03/22 22:25:55 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int pset_for(t_process *p, t_btree *ast) +{ + p->data.d_for.token = ft_ld_copy(((t_astnode *)ast->item)->data.cmd.token, + tab_esc_copy); + p->data.d_for.content = btree_map(ast->right, &node_copy); + p->type = PROCESS_FOR; + return (0); +} diff --git a/42sh/src/exec/pset_if.c b/42sh/src/exec/pset_if.c new file mode 100644 index 00000000..af80d078 --- /dev/null +++ b/42sh/src/exec/pset_if.c @@ -0,0 +1,20 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* pset_if.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/07 19:19:50 by wescande #+# #+# */ +/* Updated: 2017/03/20 16:26:35 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int pset_if(t_process *p, t_btree *ast) +{ + p->data.d_if.content = btree_map(ast->right, &node_copy); + p->type = PROCESS_IF; + return (0); +} diff --git a/42sh/src/exec/pset_subshell.c b/42sh/src/exec/pset_subshell.c new file mode 100644 index 00000000..7236a58c --- /dev/null +++ b/42sh/src/exec/pset_subshell.c @@ -0,0 +1,20 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* pset_subshell.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/08 00:02:01 by wescande #+# #+# */ +/* Updated: 2017/03/20 16:26:37 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int pset_subshell(t_process *p, t_btree *ast) +{ + p->data.subshell.content = btree_map(ast->right, &node_copy); + p->type = PROCESS_SUBSHELL; + return (0); +} diff --git a/42sh/src/exec/pset_until.c b/42sh/src/exec/pset_until.c new file mode 100644 index 00000000..df32b275 --- /dev/null +++ b/42sh/src/exec/pset_until.c @@ -0,0 +1,21 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* pset_until.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/20 16:26:43 by gwojda #+# #+# */ +/* Updated: 2017/03/20 16:26:44 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int pset_until(t_process *p, t_btree *ast) +{ + p->data.d_while.condition = btree_map(ast->left, &node_copy); + p->data.d_while.content = btree_map(ast->right, &node_copy); + p->type = PROCESS_UNTIL; + return (0); +} diff --git a/42sh/src/exec/pset_while.c b/42sh/src/exec/pset_while.c new file mode 100644 index 00000000..6202f829 --- /dev/null +++ b/42sh/src/exec/pset_while.c @@ -0,0 +1,21 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* pset_while.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/20 12:39:07 by jhalford #+# #+# */ +/* Updated: 2017/03/22 18:24:31 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int pset_while(t_process *p, t_btree *ast) +{ + p->data.d_while.condition = btree_map(ast->left, &node_copy); + p->data.d_while.content = btree_map(ast->right, &node_copy); + p->type = PROCESS_WHILE; + return (0); +} diff --git a/42sh/src/exec/redir_copy.c b/42sh/src/exec/redir_copy.c new file mode 100644 index 00000000..c5dff257 --- /dev/null +++ b/42sh/src/exec/redir_copy.c @@ -0,0 +1,29 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* redir_copy.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ariard +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/08 00:02:58 by ariard #+# #+# */ +/* Updated: 2017/03/24 17:22:23 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void *redir_copy(void *data) +{ + t_redir *old; + t_redir *new; + + if (!data) + return (NULL); + old = data; + new = (t_redir *)ft_memalloc(sizeof(t_redir)); + new->type = old->type; + new->n = old->n; + new->word = ft_strdup(old->word); + new->heredoc_data = ft_strdup(old->heredoc_data); + return (new); +} diff --git a/42sh/src/exec/redir_free.c b/42sh/src/exec/redir_free.c new file mode 100644 index 00000000..afae3991 --- /dev/null +++ b/42sh/src/exec/redir_free.c @@ -0,0 +1,27 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* redir_free.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ariard +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/03 18:12:57 by ariard #+# #+# */ +/* Updated: 2017/03/20 16:26:51 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void redir_free(void *data, size_t content_size) +{ + t_redir *redir; + + (void)content_size; + redir = data; + ft_strdel(&redir->word); + if (redir->type == TK_DLESS) + ft_strdel(&redir->heredoc_data); + redir->type = 0; + redir->n = 0; + free(redir); +} diff --git a/42sh/src/exec/redirect_dgreat.c b/42sh/src/exec/redirect_dgreat.c new file mode 100644 index 00000000..80a23adc --- /dev/null +++ b/42sh/src/exec/redirect_dgreat.c @@ -0,0 +1,28 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* redirect_dgreat.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/06 22:07:37 by jhalford #+# #+# */ +/* Updated: 2017/03/27 19:45:10 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int redirect_dgreat(t_redir *redir) +{ + int fdold; + int fdnew; + + fdnew = redir->n; + fdnew = redir->n; + if ((try_access(redir->word, 0, W_OK))) + return (ft_perror(NULL)); + if ((fdold = open(redir->word, O_WRONLY | O_CREAT | O_APPEND, 0644)) < 0) + exit(1); + fd_replace(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..e204d3c3 --- /dev/null +++ b/42sh/src/exec/redirect_dless.c @@ -0,0 +1,26 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* redirect_dless.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/20 12:36:10 by jhalford #+# #+# */ +/* Updated: 2017/03/27 19:41:50 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int redirect_dless(t_redir *redir) +{ + int fds[2]; + char *str; + + pipe(fds); + str = redir->heredoc_data; + write(fds[PIPE_WRITE], str, ft_strlen(str)); + close(fds[PIPE_WRITE]); + fd_replace(fds[PIPE_READ], redir->n); + return (0); +} diff --git a/42sh/src/exec/redirect_great.c b/42sh/src/exec/redirect_great.c new file mode 100644 index 00000000..c75cd2a0 --- /dev/null +++ b/42sh/src/exec/redirect_great.c @@ -0,0 +1,27 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* redirect_great.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/06 22:03:53 by jhalford #+# #+# */ +/* Updated: 2017/03/27 19:45:02 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int redirect_great(t_redir *redir) +{ + int fdold; + int fdnew; + + fdnew = redir->n; + if ((try_access(redir->word, 0, W_OK))) + return (ft_perror(NULL)); + if ((fdold = open(redir->word, O_WRONLY | O_CREAT | O_TRUNC, 0644)) < 0) + exit(1); + fd_replace(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..e241ba40 --- /dev/null +++ b/42sh/src/exec/redirect_greatand.c @@ -0,0 +1,39 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* redirect_greatand.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/06 22:12:31 by jhalford #+# #+# */ +/* Updated: 2017/03/27 03:18:37 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int redirect_greatand(t_redir *redir) +{ + int fdold; + int fdnew; + + if (ft_strcmp(redir->word, "-") == 0) + { + close(redir->n); + return (0); + } + if (!ft_stris(redir->word, ft_isdigit)) + { + SH_ERR("%s: can only be digits{eoc}\n", redir->word); + return (1); + } + fdold = ft_atoi(redir->word); + fdnew = redir->n; + if (fdold > 9) + return (bad_fd(fdold)); + if (fd_is_valid(fdold, O_WRONLY | O_RDWR)) + dup2(fdold, fdnew); + else + return (bad_fd(fdold)); + return (0); +} diff --git a/42sh/src/exec/redirect_less.c b/42sh/src/exec/redirect_less.c new file mode 100644 index 00000000..3c2d72de --- /dev/null +++ b/42sh/src/exec/redirect_less.c @@ -0,0 +1,27 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* redirect_less.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/06 22:09:53 by jhalford #+# #+# */ +/* Updated: 2017/03/27 19:44:56 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int redirect_less(t_redir *redir) +{ + int fdold; + int fdnew; + + fdnew = redir->n; + if ((try_access(redir->word, 1, R_OK)) != 0) + return (ft_perror(NULL)); + if ((fdold = open(redir->word, O_RDONLY, 0644)) < 0) + exit(1); + fd_replace(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..1be9e62c --- /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/03/27 03:18:44 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int redirect_lessand(t_redir *redir) +{ + int fdold; + int fdnew; + + if (ft_strcmp(redir->word, "-") == 0) + { + close(redir->n); + return (0); + } + if (!ft_stris(redir->word, ft_isdigit)) + { + SH_ERR("%s: can only be digits{eoc}\n", redir->word); + return (1); + } + fdold = ft_atoi(redir->word); + fdnew = redir->n; + if (fdold > 9) + return (bad_fd(fdold)); + if (fd_is_valid(fdold, O_RDONLY | O_RDWR)) + dup2(fdold, fdnew); + else + return (bad_fd(fdold)); + return (0); +} diff --git a/42sh/src/exec/set_exitstatus.c b/42sh/src/exec/set_exitstatus.c new file mode 100644 index 00000000..08e20c5a --- /dev/null +++ b/42sh/src/exec/set_exitstatus.c @@ -0,0 +1,34 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* set_exitstatus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/28 14:25:17 by jhalford #+# #+# */ +/* Updated: 2017/03/20 18:15:50 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void set_exitstatus(int status, int override) +{ + char *astatus; + int exitval; + + if (override) + exitval = status; + else + { + if (WIFEXITED(status)) + exitval = WEXITSTATUS(status); + else if (WIFSIGNALED(status)) + exitval = 128 + WTERMSIG(status); + else + return ; + } + astatus = ft_itoa(exitval); + builtin_setenv("setenv", (char*[]){"setenv", "?", astatus, 0}, NULL); + ft_strdel(&astatus); +} diff --git a/42sh/src/exec/token_to_argv.c b/42sh/src/exec/token_to_argv.c new file mode 100644 index 00000000..ac355f26 --- /dev/null +++ b/42sh/src/exec/token_to_argv.c @@ -0,0 +1,38 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* token_to_argv.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/07 15:55:53 by wescande #+# #+# */ +/* Updated: 2017/03/20 15:36:33 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +char **token_to_argv(t_ld *ld, int do_match) +{ + char **my_tab; + int index; + char **expand; + char **content; + + my_tab = NULL; + while (ld) + { + content = ld->content; + if ((expand = glob(content[0], + (unsigned char *)content[1], + (unsigned char *)content[2], do_match))) + { + index = -1; + while (expand[++index]) + my_tab = ft_sstradd(my_tab, expand[index]); + ft_tabdel(&expand); + } + ld = ld->next; + } + return (my_tab); +} diff --git a/42sh/src/glob/command_getoutput.c b/42sh/src/glob/command_getoutput.c new file mode 100644 index 00000000..5a96c013 --- /dev/null +++ b/42sh/src/glob/command_getoutput.c @@ -0,0 +1,68 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* command_getoutput.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/14 19:44:25 by wescande #+# #+# */ +/* Updated: 2017/03/24 14:47:25 by wescande ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" +#define BUF_SIZE 1024 + +static char *manage_output(int *fds) +{ + int ret; + char buf[BUF_SIZE + 1]; + char *output; + + output = NULL; + close(fds[PIPE_WRITE]); + while ((ret = read(fds[PIPE_READ], buf, BUF_SIZE)) > 0) + { + buf[ret] = 0; + ft_strappend(&output, buf); + } + close(fds[PIPE_READ]); + return (output); +} + +char *command_getoutput(char *command) +{ + int ret; + int pid; + int fds[2]; + char **av; + + if (!command) + return (NULL); + pipe(fds); + if (!(pid = process_fork(NULL))) + { + close(fds[PIPE_READ]); + dup2_close(fds[PIPE_WRITE], STDOUT); + av = ft_sstradd(NULL, data_singleton()->binary); + av = ft_sstradd(av, "-c"); + av = ft_sstradd(av, command); + execve(data_singleton()->binary, av, data_singleton()->env); + exit(1); + } + waitpid(pid, &ret, WUNTRACED); + return (manage_output(fds)); +} + +char *get_output(char *command) +{ + char *output; + int len; + + if (!(output = command_getoutput(command))) + return (NULL); + len = ft_strlen(output); + while (len && output[--len] == '\n') + output[len] = '\0'; + return (output); +} diff --git a/42sh/src/glob/dir_glob.c b/42sh/src/glob/dir_glob.c new file mode 100644 index 00000000..2c5f65e7 --- /dev/null +++ b/42sh/src/glob/dir_glob.c @@ -0,0 +1,66 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* dir_glob.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/30 12:07:16 by wescande #+# #+# */ +/* Updated: 2017/03/25 02:19:43 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static void dir_list_content(t_glob *gl, char **str, char *pat, + int recursive) +{ + char *path; + + if (str[1][0] != '.') + { + if (*str[0] == '/' && !*(str[0] + 1)) + path = ft_strjoin(str[0], str[1]); + else + path = ft_strjoinf(ft_strjoin(str[0], "/"), str[1], 1); + if (recursive) + dir_research(gl, path, pat, (int[]){recursive, 0}); + gl->pat = pat; + if (match_pattern(gl, str[1], path)) + { + gl->found = 1; + ft_ld_pushfront(&gl->match_tmp, ft_strdup(path + gl->cur_dir * 2 * + (path[0] == '.' && path[1] == '/'))); + } + gl->pat = pat; + ft_strdel(&path); + } +} + +int dir_research(t_glob *gl, char *p, + char *pat, int *mode) +{ + DIR *dir; + struct dirent *in; + + if (!*pat) + { + gl->found = 1; + if (!mode[1]) + ft_ld_pushfront(&gl->match_tmp, ft_strjoin(p + gl->cur_dir * 2 * + (p[0] == '.' && p[1] == '/'), "/")); + else + ft_ld_pushfront(&gl->match_tmp, ft_strdup(CH(gl->m_pat)[0])); + return (0); + } + if ((ft_strlen(p) <= 1 || p[ft_strlen(p) - 1] != '.') && is_directory(p)) + { + if (!(dir = opendir(p))) + return (0); + while ((in = readdir(dir))) + dir_list_content(gl, + (char *[2]){p, in->d_name}, pat, mode[0]); + closedir(dir); + } + return (0); +} diff --git a/42sh/src/glob/esc_print.c b/42sh/src/glob/esc_print.c new file mode 100644 index 00000000..c7362f81 --- /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/03/24 18:39:17 by wescande ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void esc_print(int fd, char *str, unsigned char *esc) +{ + char *cur; + + cur = str; + while (*cur) + { + if (is_char_esc(esc, str, cur)) + ft_dprintf(fd, "\\%c", *cur); + else + ft_dprintf(fd, "%c", *cur); + ++cur; + } + ft_dprintf(fd, "\n"); +} diff --git a/42sh/src/glob/expand_bquote.c b/42sh/src/glob/expand_bquote.c new file mode 100644 index 00000000..9b0f5bf5 --- /dev/null +++ b/42sh/src/glob/expand_bquote.c @@ -0,0 +1,135 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* expand_bquote.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/17 17:47:53 by wescande #+# #+# */ +/* Updated: 2017/03/29 14:59:17 by wescande ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.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) + 1, + ft_strlen(me->s2)}), + 0)); +} + +static void init_expand(t_bquote *me, char *content, int doifs) +{ + char *ifs; + char *content2; + + ifs = doifs ? ft_getenv(data_singleton()->local_var, "IFS") : NULL; + content = content ? ft_strtok(content, ifs) : content; + if (!content || !(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) + 1, 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) + 1, + 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 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); + } + } + return (0); +} + +static int delete(t_ld **tmp, t_ld **src) +{ + if (*tmp == *src) + ft_ld_del(src, &ft_tabdel); + else + ft_ld_del(tmp, &ft_tabdel); + return (1); +} + +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) + { + 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] - 1; + if ((tmp = gl->m_pat) && + (do_it = search_bquote(&me)) && delete(&tmp, &gl->m_pat)) + continue; + if (!gl->m_pat || !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 new file mode 100644 index 00000000..c5d48981 --- /dev/null +++ b/42sh/src/glob/expand_brace.c @@ -0,0 +1,121 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* expand_brace.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/12 19:00:29 by wescande #+# #+# */ +/* Updated: 2017/03/07 20:03:35 by wescande ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +/* +** expand_brace return expansion of a string. +** pattern searched are {ab, cd}. +** return is t_ld which first param is ab and second is cd +** input parameters are : +** -t_glob *gl -> struct of expanding +*/ + +static void iter_on_each(t_expand *me) +{ + int i; + char **my_new; + char *first; + unsigned char *second; + t_ld *wk_tmp; + + i = ft_tablen(me->split); + wk_tmp = *me->wk; + 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), + (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, NULL, 0); + ft_ld_pushfront(me->wk, my_new); + } + me->wk = &wk_tmp; +} + +static int init_expand(t_expand *me, char *start) +{ + unsigned char *esc; + + me->s1 = ft_strsub(start, 1, me->str - start - 1); + esc = ft_sub_esc(me->esc, start - CH(*me->wk)[0] + 1, me->str - start); + me->split = ft_strsplit_spe(me->s1, esc, ','); + me->m_esc = ft_strsplit_esc(me->s1, esc, ','); + ft_strdel(&me->s1); + ft_strdel((char **)&esc); + me->s1 = ft_strsub(CH(*me->wk)[0], 0, start - CH(*me->wk)[0]); + iter_on_each(me); + 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; + 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); + com += *me->str == ',' && !is_char_esc(me->esc, CH(*me->wk)[0], me->str) + && nb == 1; + if (!nb && start) + { + 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); + } + } + return (0); +} + +void expand_brace(t_glob *gl) +{ + t_ld *tmp; + int do_it; + t_expand me; + + me = (t_expand){NULL, NULL, NULL, NULL, NULL, NULL}; + do_it = 1; + while (do_it) + { + do_it = 0; + 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]; + --me.str; + if ((tmp = gl->m_pat) && + (do_it = search_brace(&me)) == 1) + ft_ld_del(&tmp, &ft_tabdel); + 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 new file mode 100644 index 00000000..d5b8104e --- /dev/null +++ b/42sh/src/glob/expand_esc.c @@ -0,0 +1,76 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* expand_esc.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/31 23:18:56 by wescande #+# #+# */ +/* Updated: 2017/02/24 22:05:26 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +unsigned char *calc_expand_esc(const unsigned char *esc, + 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[0] + + nb_end[1]) >> 3) + 1))) + return (NULL); + index = -1; + while (++index < nb_start) + new_esc[index >> 3] |= + ((esc[index >> 3] >> (7 - index % 8)) & 1) << (7 - index % 8); + pos = -1; + while (++pos < nb_middle[0]) + { + 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 >> 3] |= + ((esc[pos >> 3] >> (7 - pos % 8)) & 1) << (7 - index % 8); + ++index; + } + return (new_esc); +} + +void modify_esc_split(unsigned char *esc_dest, + unsigned char *esc_src, int start, int len) +{ + int index; + int wk; + + index = -1; + while (++index < len) + { + wk = index + start - 1; + esc_dest[wk >> 3] |= + ((esc_src[index >> 3] >> (7 - index % 8)) & 1) << (7 - wk % 8); + } +} + +unsigned char *ft_sub_esc(const unsigned char *esc, + int start, int len) +{ + unsigned char *new_esc; + int index; + + if (!(new_esc = (unsigned char *)ft_strnew(((len) >> 3) + 1))) + return (NULL); + index = -1; + while (++index < len) + { + 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_home.c b/42sh/src/glob/expand_home.c new file mode 100644 index 00000000..243d76fe --- /dev/null +++ b/42sh/src/glob/expand_home.c @@ -0,0 +1,51 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* expand_home.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/03 14:11:46 by wescande #+# #+# */ +/* Updated: 2017/03/08 23:30:32 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void do_expand_home(t_bquote *me, char *home) +{ + char **old_tab; + char **new_tab; + + old_tab = CH(*me->wk); + new_tab = gen_tab(ft_strjoin(home, me->str + 1), + calc_expand_esc(me->esc, 0, + (int[2]){ft_strlen(home), 1}, + (int[2]){1, ft_strlen(me->str) - 1}), + calc_expand_esc(me->esc2, 0, + (int[2]){ft_strlen(home), 1}, + (int[2]){1, ft_strlen(me->str) - 1}), 0); + (*me->wk)->content = new_tab; + ft_tabdel(&old_tab); +} + +void expand_home(t_glob *gl, char *home) +{ + t_bquote me; + + me = (t_bquote){NULL, NULL, NULL, NULL, NULL, NULL, NULL}; + gl->m_pat = ft_ld_front(gl->m_pat); + while (gl->m_pat) + { + 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 (!is_char_esc(me.esc, me.str, me.str) && me.str[0] == '~') + do_expand_home(&me, home); + 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_var.c b/42sh/src/glob/expand_var.c new file mode 100644 index 00000000..2bc248af --- /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/03/24 18:42:15 by wescande ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.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 - 1, 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 - 1, ft_strlen(s2)}); + ft_memdel((void **)&gl->esc2); + gl->esc2 = new_esc; + ft_strdel(&s1); + ft_strdel(&s2); +} + +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) + { + if (!(content = ft_getenv(data_singleton()->env, var))) + content = ft_getenv(data_singleton()->local_var, var); + insert_var(gl, pat, var, content); + pat = gl->pat; + } + ft_strdel(&var); + } + ++pat; + } +} diff --git a/42sh/src/glob/ft_strsplit_esc.c b/42sh/src/glob/ft_strsplit_esc.c new file mode 100644 index 00000000..57bf1439 --- /dev/null +++ b/42sh/src/glob/ft_strsplit_esc.c @@ -0,0 +1,86 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strsplit_esc.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/31 22:18:46 by wescande #+# #+# */ +/* Updated: 2017/03/22 19:24:29 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static int ft_strlen_c(const char *str, const char *fix, + const unsigned char *esc, char c) +{ + int len; + int nb; + + len = 0; + nb = 0; + while (*str && (*str != c || nb)) + { + nb += *str == '{' && !is_char_esc(esc, fix, str); + nb -= *str == '}' && !is_char_esc(esc, fix, str); + ++str; + ++len; + } + return (len); +} + +static int nb_c(const char *str, const unsigned char *esc, char c) +{ + int len; + int nb; + const char *fix; + + len = 0; + nb = 0; + fix = str; + while (*str) + { + while (*str && *str == c) + ++str; + if (*str) + ++len; + while (*str && (*str != c || nb)) + { + nb += *str == '{' && !is_char_esc(esc, fix, str); + nb -= *str == '}' && !is_char_esc(esc, fix, str); + ++str; + } + } + return (len); +} + +unsigned char **ft_strsplit_esc(const char *str, + const unsigned char *esc, char c) +{ + unsigned char **s1; + int i; + const char *fix; + int len; + int pos; + + if ((pos = -1) && !str) + return (NULL); + if (!(s1 = ft_malloc(sizeof(*s1) * (nb_c(str, esc, c) + 1)))) + return (NULL); + i = 0; + fix = str; + while (*str && *str == c && ++pos > -1) + ++str; + while (*str && (len = ft_strlen_c(str, fix, esc, c))) + { + s1[i] = ft_sub_esc(esc, pos, len); + str += len; + pos += len; + ++i; + while (*str && *str == c && ++pos) + ++str; + } + s1[i] = 0; + return (s1); +} diff --git a/42sh/src/glob/ft_strsplit_spe.c b/42sh/src/glob/ft_strsplit_spe.c new file mode 100644 index 00000000..ef2bd87a --- /dev/null +++ b/42sh/src/glob/ft_strsplit_spe.c @@ -0,0 +1,86 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strsplit_spe.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/31 20:49:30 by wescande #+# #+# */ +/* Updated: 2017/03/21 18:13:34 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static int ft_strlen_c(const char *str, const char *fix, + const unsigned char *esc, char c) +{ + int len; + int nb; + + len = 0; + nb = 0; + while (*str && (*str != c || nb)) + { + nb += *str == '{' && !is_char_esc(esc, fix, str); + nb -= *str == '}' && !is_char_esc(esc, fix, str); + ++str; + ++len; + } + return (len); +} + +static int ft_nbstr_c(const char *str, const unsigned char *esc, char c) +{ + int len; + int nb; + const char *fix; + + len = 0; + nb = 0; + fix = str; + while (*str) + { + while (*str && *str == c) + ++str; + if (*str) + ++len; + while (*str && (*str != c || nb)) + { + nb += *str == '{' && !is_char_esc(esc, fix, str); + nb -= *str == '}' && !is_char_esc(esc, fix, str); + ++str; + } + } + return (len); +} + +char **ft_strsplit_spe(const char *str, + const unsigned char *esc, char c) +{ + char **s1; + int i; + const char *fix; + int len; + + if (!str || !(s1 = + (char**)ft_malloc(sizeof(*s1) * (ft_nbstr_c(str, esc, c) + 1)))) + return (NULL); + i = 0; + fix = str; + while (*str && *str == c) + ++str; + while (*str && (len = ft_strlen_c(str, fix, esc, c))) + { + if (!(s1[i] = (char*)ft_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) + ++str; + } + s1[i] = 0; + return (s1); +} diff --git a/42sh/src/glob/gen_tab_esc.c b/42sh/src/glob/gen_tab_esc.c new file mode 100644 index 00000000..700be3e8 --- /dev/null +++ b/42sh/src/glob/gen_tab_esc.c @@ -0,0 +1,45 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* gen_tab_esc.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/07 20:04:40 by wescande #+# #+# */ +/* Updated: 2017/03/21 18:13:39 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +char **gen_tab(const char *pat, + const unsigned char *esc, + const unsigned char *esc2, + int dup) +{ + char **my_tab; + int len; + + if (!(my_tab = (char **)ft_malloc(sizeof(char *) * (esc2 ? 4 : 3)))) + return (NULL); + if (dup) + { + len = ft_strlen(pat); + my_tab[0] = ft_strdup(pat); + my_tab[1] = (char *)dup_char_esc(esc, (len >> 3) + 1); + if (esc2) + my_tab[2] = (char *)dup_char_esc(esc2, (len >> 3) + 1); + } + else + { + my_tab[0] = (char *)pat; + my_tab[1] = (char *)esc; + if (esc2) + my_tab[2] = (char *)esc2; + } + if (esc2) + my_tab[3] = NULL; + else + my_tab[2] = NULL; + return (my_tab); +} diff --git a/42sh/src/glob/glob.c b/42sh/src/glob/glob.c new file mode 100644 index 00000000..0a56acfd --- /dev/null +++ b/42sh/src/glob/glob.c @@ -0,0 +1,111 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* glob.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/04 16:29:54 by wescande #+# #+# */ +/* Updated: 2017/03/14 23:30:59 by wescande ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +/* +** glob return expansion of a string. +** pattern searched are *, ?, [a-z], [!a-z], [^a-z], {ab, ac}, ** +** input parameters are : +** -char *pat -> pattern string to be looking for match +** -char *esc -> escape binary sequence of *pat +** -char **env -> env var. could be NULL +** to just expanse in local directory and not in path dir +*/ + +static int order_glob(const char *s1, const char *s2) +{ + char c1; + char c2; + + if (!s1 || !s2) + return (1); + c1 = ft_tolower(*s1++); + c2 = ft_tolower(*s2++); + if (!c1) + return (-(c1 - c2)); + while (c1 == c2) + { + c1 = ft_tolower(*s1++); + c2 = ft_tolower(*s2++); + if (!c1) + return (-(c1 - c2)); + } + return (-(c1 - c2)); +} + +static void merge_ld_glob(t_ld **match, t_ld **tmp) +{ + t_ld *ultimate; + + *tmp = ft_ld_order(*tmp, &order_glob); + ultimate = ft_ld_back(*tmp); + ultimate->next = *match; + if (*match) + (*match)->prev = ultimate; + *match = *tmp; + *tmp = NULL; +} + +static char **treat_glob(t_glob *gl) +{ + char **ret; + + 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); +} + +static void normal_expand_before_match(t_glob *gl, int do_match) +{ + char *home; + + expand_var(gl); + expand_bquote(gl); + if (do_match) + expand_brace(gl); + if ((home = ft_getenv(data_singleton()->env, "HOME"))) + expand_home(gl, home); +} + +char **glob(char *pat, unsigned char *esc, + unsigned char *esc2, int do_match) +{ + t_glob gl; + int len; + + 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, NULL}; + normal_expand_before_match(&gl, do_match); + if (do_match) + while (gl.m_pat && !(gl.found = 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, (int[]){0, 1}); + else + dir_research(&gl, "/", gl.pat + 1, (int[]){0, 1}); + if (!gl.found) + ft_ld_pushfront(&gl.match, ft_strdup(CH(gl.m_pat)[0])); + else + merge_ld_glob(&gl.match, &gl.match_tmp); + if (!gl.m_pat->next) + break ; + gl.m_pat = gl.m_pat->next; + } + return (treat_glob(&gl)); +} diff --git a/42sh/src/glob/is_char_esc.c b/42sh/src/glob/is_char_esc.c new file mode 100644 index 00000000..083556e5 --- /dev/null +++ b/42sh/src/glob/is_char_esc.c @@ -0,0 +1,71 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* is_char_esc.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/27 18:19:55 by wescande #+# #+# */ +/* Updated: 2017/03/17 19:31:16 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +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 (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); + new_esc = ft_memcpy(new_esc, esc, size); + return (new_esc); +} diff --git a/42sh/src/glob/lib_perso/ft_ld_back.c b/42sh/src/glob/lib_perso/ft_ld_back.c new file mode 100644 index 00000000..de2cc45e --- /dev/null +++ b/42sh/src/glob/lib_perso/ft_ld_back.c @@ -0,0 +1,21 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_ld_back.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/16 16:23:26 by wescande #+# #+# */ +/* Updated: 2017/03/23 06:00:13 by wescande ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +t_ld *ft_ld_back(t_ld *ld) +{ + if (ld) + while (ld->next) + ld = ld->next; + return (ld); +} diff --git a/42sh/src/glob/lib_perso/ft_ld_clear.c b/42sh/src/glob/lib_perso/ft_ld_clear.c new file mode 100644 index 00000000..3cbdf315 --- /dev/null +++ b/42sh/src/glob/lib_perso/ft_ld_clear.c @@ -0,0 +1,24 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_ld_clear.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/06 19:56:49 by wescande #+# #+# */ +/* Updated: 2017/03/21 18:41:08 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void ft_ld_clear(t_ld **ld, void (*del)()) +{ + if (!ld || !*ld) + return ; + *ld = ft_ld_front(*ld); + while (*ld) + { + ft_ld_del(ld, del); + } +} diff --git a/42sh/src/glob/lib_perso/ft_ld_copy.c b/42sh/src/glob/lib_perso/ft_ld_copy.c new file mode 100644 index 00000000..86d43dcc --- /dev/null +++ b/42sh/src/glob/lib_perso/ft_ld_copy.c @@ -0,0 +1,29 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_ld_copy.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/07 19:42:23 by wescande #+# #+# */ +/* Updated: 2017/03/08 00:58:50 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +t_ld *ft_ld_copy(t_ld *src, void *(*f)(void *elem)) +{ + t_ld *dst; + void *content; + + dst = NULL; + while (src) + { + content = (*f)(src->content); + ft_ld_pushfront(&dst, content); + src = src->next; + } + ft_ld_reverse(&dst); + return (dst); +} diff --git a/42sh/src/glob/lib_perso/ft_ld_del.c b/42sh/src/glob/lib_perso/ft_ld_del.c new file mode 100644 index 00000000..84fcb403 --- /dev/null +++ b/42sh/src/glob/lib_perso/ft_ld_del.c @@ -0,0 +1,36 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_ld_del.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/06 15:54:53 by wescande #+# #+# */ +/* Updated: 2017/03/21 18:26:53 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void ft_ld_del(t_ld **ld, void (*del)()) +{ + t_ld *next; + t_ld *prev; + + if (!ld || !*ld) + return ; + next = (*ld)->next; + prev = (*ld)->prev; + if ((*ld)->content && del) + del(&(*ld)->content); + free(*ld); + if (next) + next->prev = prev; + if (prev) + { + prev->next = next; + *ld = prev; + } + else + *ld = next; +} diff --git a/42sh/src/glob/lib_perso/ft_ld_front.c b/42sh/src/glob/lib_perso/ft_ld_front.c new file mode 100644 index 00000000..72b23b56 --- /dev/null +++ b/42sh/src/glob/lib_perso/ft_ld_front.c @@ -0,0 +1,21 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_ld_front.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/01 18:26:11 by wescande #+# #+# */ +/* Updated: 2017/03/23 06:01:02 by wescande ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +t_ld *ft_ld_front(t_ld *ld) +{ + if (ld) + while (ld->prev) + ld = ld->prev; + return (ld); +} diff --git a/42sh/src/glob/lib_perso/ft_ld_new.c b/42sh/src/glob/lib_perso/ft_ld_new.c new file mode 100644 index 00000000..a457b626 --- /dev/null +++ b/42sh/src/glob/lib_perso/ft_ld_new.c @@ -0,0 +1,26 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_ld_new.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/01 18:17:34 by wescande #+# #+# */ +/* Updated: 2017/03/21 18:12:52 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void ft_ld_new(t_ld **alst, void *content) +{ + t_ld *new; + + if ((new = (t_ld *)ft_malloc(sizeof(t_ld)))) + { + new->content = content; + new->prev = NULL; + new->next = NULL; + *alst = new; + } +} diff --git a/42sh/src/glob/lib_perso/ft_ld_order.c b/42sh/src/glob/lib_perso/ft_ld_order.c new file mode 100644 index 00000000..1dc2877d --- /dev/null +++ b/42sh/src/glob/lib_perso/ft_ld_order.c @@ -0,0 +1,35 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_ld_order.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/24 19:20:45 by wescande #+# #+# */ +/* Updated: 2017/03/07 21:19:13 by wescande ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +t_ld *ft_ld_order(t_ld *ld, int (*f)()) +{ + int swap; + + swap = 1; + ld = ft_ld_front(ld); + if (!f) + return (ld); + while (swap) + { + swap = 0; + while (ld && ld->next) + { + if (f(ld->content, ld->next->content) > 0 && (swap = 1)) + ld = ft_ld_swap(ld); + ld = ld->next; + } + ld = ft_ld_front(ld); + } + return (ld); +} diff --git a/42sh/src/glob/lib_perso/ft_ld_pushback.c b/42sh/src/glob/lib_perso/ft_ld_pushback.c new file mode 100644 index 00000000..99fd42aa --- /dev/null +++ b/42sh/src/glob/lib_perso/ft_ld_pushback.c @@ -0,0 +1,30 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_ld_pushback.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/16 15:59:38 by wescande #+# #+# */ +/* Updated: 2017/03/21 18:12:58 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void ft_ld_pushback(t_ld **alst, void *content) +{ + t_ld *new; + t_ld *back; + + if (!alst || !*alst) + return (ft_ld_new(alst, content)); + if ((new = (t_ld *)ft_malloc(sizeof(t_ld)))) + { + back = ft_ld_back(*alst); + new->prev = back; + new->next = NULL; + new->content = content; + back->next = new; + } +} diff --git a/42sh/src/glob/lib_perso/ft_ld_pushfront.c b/42sh/src/glob/lib_perso/ft_ld_pushfront.c new file mode 100644 index 00000000..2a80b101 --- /dev/null +++ b/42sh/src/glob/lib_perso/ft_ld_pushfront.c @@ -0,0 +1,31 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_ld_pushfront.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/01 18:32:40 by wescande #+# #+# */ +/* Updated: 2017/03/21 18:13:02 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void ft_ld_pushfront(t_ld **alst, void *content) +{ + t_ld *new; + t_ld *front; + + if (!alst || !*alst) + return (ft_ld_new(alst, content)); + if ((new = (t_ld *)ft_malloc(sizeof(t_ld)))) + { + front = ft_ld_front(*alst); + new->next = front; + new->prev = NULL; + new->content = content; + front->prev = new; + *alst = new; + } +} diff --git a/42sh/src/glob/lib_perso/ft_ld_reverse.c b/42sh/src/glob/lib_perso/ft_ld_reverse.c new file mode 100644 index 00000000..7dc87189 --- /dev/null +++ b/42sh/src/glob/lib_perso/ft_ld_reverse.c @@ -0,0 +1,32 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_ld_reverse.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/12 14:16:04 by wescande #+# #+# */ +/* Updated: 2017/03/07 21:20:35 by wescande ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void ft_ld_reverse(t_ld **lst) +{ + t_ld *l_prev; + t_ld *l_next; + t_ld *l_cur; + + l_cur = ft_ld_front(*lst); + l_prev = NULL; + while (l_cur) + { + l_next = l_cur->next; + l_cur->next = l_prev; + l_cur->prev = l_next; + l_prev = l_cur; + l_cur = l_next; + } + *lst = l_prev; +} diff --git a/42sh/src/glob/lib_perso/ft_ld_size.c b/42sh/src/glob/lib_perso/ft_ld_size.c new file mode 100644 index 00000000..ae12022d --- /dev/null +++ b/42sh/src/glob/lib_perso/ft_ld_size.c @@ -0,0 +1,27 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_ld_size.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/01 18:33:48 by wescande #+# #+# */ +/* Updated: 2017/03/07 21:19:26 by wescande ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +size_t ft_ld_size(t_ld *ld) +{ + size_t size; + + size = 0; + ld = ft_ld_front(ld); + while (ld) + { + ++size; + ld = ld->next; + } + return (size); +} diff --git a/42sh/src/glob/lib_perso/ft_ld_swap.c b/42sh/src/glob/lib_perso/ft_ld_swap.c new file mode 100644 index 00000000..638df672 --- /dev/null +++ b/42sh/src/glob/lib_perso/ft_ld_swap.c @@ -0,0 +1,35 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_ld_swap.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/24 21:12:53 by wescande #+# #+# */ +/* Updated: 2017/03/23 06:01:07 by wescande ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +t_ld *ft_ld_swap(t_ld *l_cur) +{ + t_ld *l_next; + t_ld *l_prev; + + l_next = l_cur; + if (l_cur && l_cur->next) + { + l_prev = l_cur->prev; + l_next = l_cur->next; + l_cur->next = l_next->next; + if (l_cur->next) + l_cur->next->prev = l_cur; + l_cur->prev = l_next; + l_next->next = l_cur; + l_next->prev = l_prev; + if (l_prev) + l_prev->next = l_next; + } + return (l_next); +} diff --git a/42sh/src/glob/lib_perso/ft_ld_to_tab.c b/42sh/src/glob/lib_perso/ft_ld_to_tab.c new file mode 100644 index 00000000..b2c99272 --- /dev/null +++ b/42sh/src/glob/lib_perso/ft_ld_to_tab.c @@ -0,0 +1,34 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_ld_to_tab.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/05 16:17:00 by wescande #+# #+# */ +/* Updated: 2017/03/21 18:13:08 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +char **ft_ld_to_tab(t_ld *ld) +{ + char **my_tab; + int nb_item; + int index; + + if (!ld) + return (NULL); + nb_item = ft_ld_size(ld); + if (!(my_tab = (char **)ft_malloc(sizeof(char *) * (nb_item + 1)))) + return (NULL); + index = 0; + while (ld) + { + my_tab[index++] = ft_strdup((char *)ld->content); + ld = ld->next; + } + my_tab[index] = NULL; + return (my_tab); +} 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..50cbeb11 --- /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/03/07 21:19:39 by wescande ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.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/src/glob/lib_perso/ft_strjoinf.c b/42sh/src/glob/lib_perso/ft_strjoinf.c new file mode 100644 index 00000000..d860b34c --- /dev/null +++ b/42sh/src/glob/lib_perso/ft_strjoinf.c @@ -0,0 +1,25 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strjoinf.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/05 13:33:24 by wescande #+# #+# */ +/* Updated: 2017/03/07 21:19:55 by wescande ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +char *ft_strjoinf(char *s1, char *s2, int state) +{ + char *ans; + + ans = ft_strjoin((const char *)s1, (const char *)s2); + if (state == 1 || state == 3) + ft_strdel(&s1); + if (state == 2 || state == 3) + ft_strdel(&s2); + return (ans); +} diff --git a/42sh/src/glob/lib_perso/ft_strsubf.c b/42sh/src/glob/lib_perso/ft_strsubf.c new file mode 100644 index 00000000..72bcb016 --- /dev/null +++ b/42sh/src/glob/lib_perso/ft_strsubf.c @@ -0,0 +1,25 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strsubf.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/15 17:20:08 by wescande #+# #+# */ +/* Updated: 2017/03/07 21:20:19 by wescande ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +char *ft_strsubf(char *s, unsigned int start, size_t len, short int mode) +{ + char *sptr; + + if (!s) + return (NULL); + sptr = ft_strsub(s, start, len); + if (mode == 1) + ft_strdel(&s); + return (sptr); +} diff --git a/42sh/src/glob/lib_perso/ft_tabdel.c b/42sh/src/glob/lib_perso/ft_tabdel.c new file mode 100644 index 00000000..80d56c90 --- /dev/null +++ b/42sh/src/glob/lib_perso/ft_tabdel.c @@ -0,0 +1,31 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* glob.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/04 16:29:54 by wescande #+# #+# */ +/* Updated: 2017/03/21 18:41:20 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void ft_tabdel(char ***mytab) +{ + char **erase; + int i; + + if (!mytab || !*mytab) + return ; + erase = *mytab; + i = 0; + while (erase[i]) + { + ft_strdel(&erase[i]); + ++i; + } + free(*mytab); + *mytab = NULL; +} diff --git a/42sh/src/glob/lib_perso/ft_tablen.c b/42sh/src/glob/lib_perso/ft_tablen.c new file mode 100644 index 00000000..149cd7ca --- /dev/null +++ b/42sh/src/glob/lib_perso/ft_tablen.c @@ -0,0 +1,27 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_tablen.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/28 16:54:07 by wescande #+# #+# */ +/* Updated: 2017/03/07 21:18:23 by wescande ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int ft_tablen(char **mytab) +{ + int i; + + if (!mytab || !*mytab) + return (0); + i = 0; + while (mytab[i]) + { + ++i; + } + return (i); +} diff --git a/42sh/src/glob/match_pattern.c b/42sh/src/glob/match_pattern.c new file mode 100644 index 00000000..7ac647e6 --- /dev/null +++ b/42sh/src/glob/match_pattern.c @@ -0,0 +1,133 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* match_pattern.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/24 17:30:23 by wescande #+# #+# */ +/* Updated: 2017/03/23 03:16:08 by wescande ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static int match_bracket_char(char **cmp, const char *pat, char c, int neg) +{ + int dir; + char s; + + if ((*cmp + 2) < pat && (*cmp)[1] == '-' && (s = (*cmp)[0])) + { + dir = s > (*cmp)[2]; + while ((dir && s >= (*cmp)[2]) || (!dir && s <= (*cmp)[2])) + { + if (!neg && s == c) + return (1); + else if (neg && s == c) + return (0); + s += (dir * -2 + 1); + } + *cmp += 2; + } + else if (!neg && **cmp == c) + return (1); + else if (neg && **cmp == c) + return (0); + return (-1); +} + +static int match_bracket(t_glob *gl, char c) +{ + char *cmp; + int neg; + int ret; + + cmp = (char *)gl->pat + 1; + while (*gl->pat != ']' + || is_char_esc(gl->esc, ((char **)gl->m_pat->content)[0], gl->pat)) + { + if (!*gl->pat) + return (0); + ++gl->pat; + } + neg = 0; + if ((*cmp == '^' || *cmp == '!') + && !is_char_esc(gl->esc, ((char **)gl->m_pat->content)[0], cmp) + && ++neg) + ++cmp; + while (cmp < gl->pat) + { + ret = match_bracket_char(&cmp, gl->pat, c, neg); + if (ret != -1) + return (ret); + ++cmp; + } + return (neg); +} + +static int match_star(t_glob *gl, char *str, char *full_word) +{ + char *fix; + char *pat; + + if (!is_char_esc(gl->esc, ((char **)gl->m_pat->content)[0], gl->pat + 1) + && gl->pat[1] == '*') + { + while (gl->pat[1] == '*') + ++gl->pat; + dir_research(gl, full_word, gl->pat, (int[]){1, 0}); + } + if (!*gl->pat || (*gl->pat == '*' && !*++gl->pat)) + return (1); + pat = gl->pat; + fix = str + ft_strlen(str); + while (fix > str) + { + gl->pat = pat; + if (match_pattern(gl, fix, full_word)) + return (1); + --fix; + } + return (0); +} + +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, gl->pat, str); + while (*gl->pat) + { + if (is_char_esc(gl->esc, ((char **)gl->m_pat->content)[0], gl->pat)) + { + if (*str != *gl->pat) + return (0); + } + else if (*gl->pat == '?' && *str) + ; + else if (*gl->pat == '[') + { + if (!match_bracket(gl, *str)) + return (0); + } + else if (*gl->pat == '*') + return (match_star(gl, str, full_word)); + else if (*gl->pat == '/' && !*str && is_directory(full_word)) + return (dir_research(gl, full_word, gl->pat + 1, (int[]){0, 0})); + else if (*gl->pat != *str) + return (0); + ++str; + ++gl->pat; + } + return (*str ? 0 : 1); +} diff --git a/42sh/src/glob/tab_esc_copy.c b/42sh/src/glob/tab_esc_copy.c new file mode 100644 index 00000000..e26b91c8 --- /dev/null +++ b/42sh/src/glob/tab_esc_copy.c @@ -0,0 +1,23 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* tab_esc_copy.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/23 05:37:19 by wescande #+# #+# */ +/* Updated: 2017/03/23 05:55:01 by wescande ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void *tab_esc_copy(void *content) +{ + char **ch_cont; + + ch_cont = (char **)content; + return (gen_tab(ch_cont[0], + (unsigned char *)ch_cont[1], + (unsigned char *)ch_cont[2], 1)); +} diff --git a/42sh/src/glob/word_is_assignment.c b/42sh/src/glob/word_is_assignment.c new file mode 100644 index 00000000..cc010e51 --- /dev/null +++ b/42sh/src/glob/word_is_assignment.c @@ -0,0 +1,34 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* word_is_assignment.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/07 18:59:11 by wescande #+# #+# */ +/* Updated: 2017/03/15 20:55:15 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int word_is_assignment(char **content) +{ + const int len = ft_strlen(content[0]); + int pos; + char c; + const unsigned char *esc = (const unsigned char *)content[1]; + + pos = -1; + if (ft_isdigit(content[0][0])) + return (0); + while (++pos < len) + { + if (is_char_esc(esc, content[0], content[0] + pos)) + return (0); + c = content[0][pos]; + if (!ft_isalnum(c) && c != '_') + return (0); + } + return (1); +} 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..1c4e63f3 --- /dev/null +++ b/42sh/src/hash_table/ft_add_hash.c @@ -0,0 +1,30 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_add_hash.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/18 11:20:11 by gwojda #+# #+# */ +/* Updated: 2017/03/21 17:40:13 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +#define BACKUP_PATH "/bin:/usr/bin" + +char *ft_add_hash(char *cmd) +{ + int id; + t_hash hash; + char *path; + + path = ft_getenv(data_singleton()->env, "PATH"); + if (!(hash.path = ft_findexec(path ? path : BACKUP_PATH, cmd))) + return (NULL); + hash.key = ft_strdup(cmd); + id = ft_hash_str(cmd); + ft_lsteadd(&(g_hash[id]), ft_lstnew(&hash, sizeof(t_hash))); + return (ft_strdup(hash.path)); +} diff --git a/42sh/src/hash_table/hash.c b/42sh/src/hash_table/hash.c new file mode 100644 index 00000000..846643e0 --- /dev/null +++ b/42sh/src/hash_table/hash.c @@ -0,0 +1,24 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* hash.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/18 11:06:19 by gwojda #+# #+# */ +/* Updated: 2017/03/21 17:40:19 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +t_list *g_hash[MAX_HASH] = {NULL}; + +char *ft_hash(char *cmd) +{ + char *path; + + if (!(path = ft_is_hash(cmd))) + path = ft_add_hash(cmd); + return (path); +} 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..6755896a --- /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/03/04 18:51:14 by ariard ### ########.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..09abc922 --- /dev/null +++ b/42sh/src/hash_table/is_hash.c @@ -0,0 +1,49 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* is_hash.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/18 11:08:40 by gwojda #+# #+# */ +/* Updated: 2017/03/29 15:25:58 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static char *h_free_one(t_list **head, t_list *list, t_list *ref) +{ + if (!((*head)->next)) + ft_lstdelone(head, &ft_hash_free); + else + { + ref->next = list->next; + ft_lstdelone(&list, &ft_hash_free); + } + return (NULL); +} + +char *ft_is_hash(char *cmd) +{ + t_list *list; + t_list *ref; + int id; + + id = ft_hash_str(cmd); + list = g_hash[id]; + ref = list; + while (list) + { + if (!ft_strcmp(((t_hash *)list->content)->key, cmd)) + { + if (access(((t_hash *)list->content)->path, + X_OK | F_OK) < 0) + return (h_free_one(&g_hash[id], list, ref)); + return (ft_strdup(((t_hash *)list->content)->path)); + } + ref = list; + list = list->next; + } + return (NULL); +} 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..bfb83140 --- /dev/null +++ b/42sh/src/history/add_str_in_history.c @@ -0,0 +1,52 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* add_str_in_history.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/14 11:27:03 by gwojda #+# #+# */ +/* Updated: 2017/03/26 21:59:21 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void ft_add_in_history_file(char *str) +{ + int fd; + int i; + char *home; + char *path; + char **hist; + + i = 0; + if (!(home = ft_getenv(data_singleton()->env, "HOME"))) + return ; + hist = ft_strsplit(str, '\n'); + path = ft_str3join(home, "/", ".42sh_history"); + fd = open(path, O_CREAT | O_WRONLY | O_APPEND, S_IWUSR | S_IRUSR); + if (fd > 0) + { + while (hist[i]) + { + write(fd, hist[i], ft_strlen(hist[i])); + write(fd, "\n", 1); + ++i; + } + close(fd); + } + ft_sstrfree(hist); + free(path); +} + +void ft_add_str_in_history(char *str) +{ + if (str && *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..48be8f6f --- /dev/null +++ b/42sh/src/history/history.c @@ -0,0 +1,76 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* history.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/02 15:22:19 by gwojda #+# #+# */ +/* Updated: 2017/03/17 16:05:47 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static void ft_clear_before_history(char **str) +{ + if (*str) + { + if (data_singleton()->line.pos) + { + --data_singleton()->line.pos; + ft_get_beggin_with_curs(*str, &data_singleton()->line.pos); + } + ft_puttermcaps("cd"); + data_singleton()->line.pos = 0; + ft_strdel(str); + } +} + +int ft_history_down(char **str, size_t *pos) +{ + t_list_history *head; + + head = data_singleton()->line.list_cur; + if (!head) + return (0); + ft_clear_before_history(str); + if (head->next) + head = head->next; + if (!head->str) + *str = NULL; + else if (!(*str = ft_strdup(head->str))) + return (-1); + if (*str) + ft_current_str(*str, *pos); + if (*str) + *pos = ft_strlen_next(*str, *pos); + else + *pos = 0; + data_singleton()->line.list_cur = head; + return (0); +} + +int ft_history_up(char **str, size_t *pos) +{ + t_list_history *head; + + head = data_singleton()->line.list_cur; + if (!head) + return (0); + ft_clear_before_history(str); + if (head->prev) + head = head->prev; + if (!head->str) + *str = NULL; + else if (!(*str = ft_strdup(head->str))) + return (-1); + if (*str) + ft_current_str(*str, *pos); + if (*str) + *pos = ft_strlen_next(*str, *pos); + else + *pos = 0; + data_singleton()->line.list_cur = head; + return (0); +} diff --git a/42sh/src/history/history_parsing.c b/42sh/src/history/history_parsing.c new file mode 100644 index 00000000..a459e0f9 --- /dev/null +++ b/42sh/src/history/history_parsing.c @@ -0,0 +1,117 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* history_parsing.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/25 11:39:47 by gwojda #+# #+# */ +/* Updated: 2017/03/27 19:44:48 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static int history_parsing_nb_and_previous(char *str, int *i) +{ + int tmp; + + if (!ft_strncmp("!!", str + *i, 2)) + { + ft_realloc_str_history(&(data_singleton()->line.input), *i, 0, 2); + (*i) += 2; + return (1); + } + else if (str[*i + 1] == '-' && ft_isdigit(str[*i + 2]) && + (size_t)ft_atoi(str + (*i) + 2) < ft_hist_len()) + { + tmp = ft_nbr_len(ft_atoi(str + *i + 2)); + ft_realloc_str_history(&(data_singleton()->line.input), *i, + ft_atoi(str + (*i) + 2), ft_nbr_len(ft_atoi(str + *i + 2)) + 2); + (*i) += tmp; + return (1); + } + return (0); +} + +static int check_validity(char *str, int i) +{ + if (i && str[i - 1] == '\\') + return (0); + else if (!str[i + 1] || str[i + 1] == '"') + return (0); + return (1); +} + +static int history_parsing_nb_and_name(char *str, int *i) +{ + int tmp; + + if (!check_validity(str, *i)) + return (0); + if (history_parsing_nb_and_previous(str, i)) + return (1); + else if (ft_isdigit(str[(*i) + 1]) && (size_t)ft_atoi(str + (*i) + 1) < + ft_hist_len()) + { + tmp = ft_nbr_len(ft_atoi(str + *i + 1)); + ft_realloc_str_history(&(data_singleton()->line.input), *i, + data_singleton()->line.list_size - ft_atoi(str + *i + 1), + ft_nbr_len(ft_atoi(str + *i + 1)) + 1); + 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] && str[*i + 1] != ' ') + ft_realloc_str_history_2(&(data_singleton()->line.input), *i, + c_strdupi(str + *i + 1, hist_is_delim)); + else + return (0); + return (1); +} + +static int rematch_history_parsing(int has_prompt, char **input) +{ + int ret; + + data_singleton()->line.pos = 0; + has_prompt ? ft_prompt() : ft_putstr("> "); + if ((ret = ft_read_stdin(input)) < 0) + return (-1); + if (data_singleton()->line.input) + ft_current_str(data_singleton()->line.input, + data_singleton()->line.pos); + ft_putchar('\n'); + ft_history_parsing(has_prompt, input); + return (ret); +} + +int ft_history_parsing(int has_prompt, char **input) +{ + int i; + char boolean; + char quote; + + i = 0; + quote = 0; + boolean = 0; + while (data_singleton()->line.input && data_singleton()->line.input[i]) + { + if (data_singleton()->line.input[i] == '\'') + quote = quote ? 0 : 1; + if (!quote && data_singleton()->line.input[i] == '!') + { + boolean = 1; + if (!history_parsing_nb_and_name(data_singleton()->line.input, &i)) + boolean = 0; + else + i = -1; + } + ++i; + } + *input = data_singleton()->line.input; + if (boolean) + return (rematch_history_parsing(has_prompt, input)); + return (0); +} diff --git a/42sh/src/history/history_parsing_toolz.c b/42sh/src/history/history_parsing_toolz.c new file mode 100644 index 00000000..c6d0272f --- /dev/null +++ b/42sh/src/history/history_parsing_toolz.c @@ -0,0 +1,100 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* history_parsing_toolz.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/25 14:09:39 by gwojda #+# #+# */ +/* Updated: 2017/03/27 18:07:49 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int hist_is_delim(char c) +{ + if (c == ' ' || c == '"') + return (1); + return (0); +} + +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 && 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 && 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..81717257 --- /dev/null +++ b/42sh/src/history/history_parsing_toolz_2.c @@ -0,0 +1,62 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* history_parsing_toolz_2.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/25 20:04:16 by gwojda #+# #+# */ +/* Updated: 2017/03/22 11:56:47 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); + new_str3 = ft_strjoin(new_str2, (*str) + pos + ft_strlen(s) + 2); + free(new_str2); + } + free(new_str); + ft_strdel(str); + *str = new_str3; + free(s); +} diff --git a/42sh/src/history/list_toolz.c b/42sh/src/history/list_toolz.c new file mode 100644 index 00000000..096bec47 --- /dev/null +++ b/42sh/src/history/list_toolz.c @@ -0,0 +1,83 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* list_toolz.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/17 11:37:47 by gwojda #+# #+# */ +/* Updated: 2017/03/21 18:12:27 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void free_history_list(t_list_history *head) +{ + t_list_history *prev; + + if (!SH_IS_INTERACTIVE(data_singleton()->opts)) + return ; + if (head && head->next) + free(head->next); + while (head) + { + ft_strdel(&head->str); + prev = head; + head = head->prev; + free(prev); + } +} + +t_list_history *ft_create_history_list(char *str) +{ + t_list_history *list; + + list = (t_list_history *)ft_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; +} + +size_t ft_hist_len(void) +{ + size_t len; + t_list_history *list; + + len = 0; + list = data_singleton()->line.list_beg; + while (list) + { + ++len; + list = list->prev; + } + return (len); +} diff --git a/42sh/src/history/surch_in_history.c b/42sh/src/history/surch_in_history.c new file mode 100644 index 00000000..bd943423 --- /dev/null +++ b/42sh/src/history/surch_in_history.c @@ -0,0 +1,98 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* surch_in_history.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/26 10:43:16 by gwojda #+# #+# */ +/* Updated: 2017/03/28 12:22:12 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static void ft_clear_prompt(size_t *pos, size_t srch_pos) +{ + if (*pos) + { + ft_putnc('\b', *pos); + (*pos) = 0; + } + ft_putnc('\b', data_singleton()->line.prompt_size + srch_pos + 1); + ft_puttermcaps("cd"); +} + +static int search(char **str, char **str_srch, + int ret, size_t *srch_pos) +{ + if (!(*str_srch = ft_realloc_imput(*str_srch, ret, *srch_pos))) + return (-1); + ++(*srch_pos); + *str = ft_strget_history(*str_srch); + return (1); +} + +static void ft_give_new_prompt(char *str_srch, size_t srch_pos) +{ + ft_clear_prompt(&data_singleton()->line.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 (data_singleton()->line.input) + { + ft_current_str(data_singleton()->line.input, + data_singleton()->line.pos); + ft_get_next_str(data_singleton()->line.input, + &data_singleton()->line.pos); + } +} + +static int ft_modify_str(char *str_srch, size_t srch_pos, char **str, + size_t *pos) +{ + ft_clear_prompt(pos, srch_pos); + data_singleton()->line.is_prompt ? ft_prompt() : ft_putstr("> "); + if (*str) + { + *str = ft_strdup(*str); + ft_current_str(*str, *pos); + ft_get_next_str(*str, pos); + if ((*str)[*pos]) + ++(*pos); + } + free(str_srch); + return (0); +} + +int ft_surch_in_history(char **str, size_t *pos) +{ + char *str_srch; + int ret; + size_t srch_pos; + + srch_pos = 0; + str_srch = NULL; + (*str) ? ft_strdel(str) : 0; + while (42) + { + ft_give_new_prompt(str_srch, srch_pos); + ret = 0; + read(0, &ret, sizeof(int)); + if (ft_isprint(ret) && search(str, &str_srch, ret, &srch_pos) < 0) + return (-1); + else if (!ft_isprint(ret) && ret == 127 && srch_pos) + { + --srch_pos; + str_srch = ft_remove_imput(str_srch, srch_pos); + ft_puttermcaps("le"); + *str = (!*str_srch) ? NULL : ft_strget_history(str_srch); + } + else if (ret != 127 && !ft_isprint(ret)) + break ; + } + return (ft_modify_str(str_srch, srch_pos, str, pos)); +} diff --git a/42sh/src/job_control/builtin_bg.c b/42sh/src/job_control/builtin_bg.c new file mode 100644 index 00000000..08c5fdfb --- /dev/null +++ b/42sh/src/job_control/builtin_bg.c @@ -0,0 +1,42 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* builtin_bg.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/09 16:54:18 by jhalford #+# #+# */ +/* Updated: 2017/03/22 19:29:32 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int builtin_bg(const char *path, char *const av[], char *const envp[]) +{ + t_jobc *jobc; + t_list *jlist; + int rank[2]; + int id; + + (void)path; + (void)envp; + if (!SH_HAS_JOBC(data_singleton()->opts)) + { + SH_ERR("bg: %s", SH_MSG_NOJOBC); + return (-1); + } + jobc = &data_singleton()->jobc; + job_getrank(&rank); + id = av[1] ? ft_atoi(av[1]) : rank[0]; + if ((jlist = ft_lst_find(jobc->first_job, &id, job_cmp_id))) + { + job_run(jlist->content, 0); + return (0); + } + else if (av[1]) + SH_ERR("bg: job not found: [%i]", id); + else + SH_ERR("bg: no current job"); + return (1); +} diff --git a/42sh/src/job_control/builtin_fg.c b/42sh/src/job_control/builtin_fg.c new file mode 100644 index 00000000..fd61c7ea --- /dev/null +++ b/42sh/src/job_control/builtin_fg.c @@ -0,0 +1,42 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* builtin_fg.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/08 14:30:07 by jhalford #+# #+# */ +/* Updated: 2017/03/22 19:31:00 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int builtin_fg(const char *path, char *const av[], char *const envp[]) +{ + t_jobc *jobc; + t_list *jlist; + int rank[2]; + int id; + + (void)path; + (void)envp; + if (!SH_HAS_JOBC(data_singleton()->opts)) + { + SH_ERR("fg: %s", SH_MSG_NOJOBC); + return (-1); + } + jobc = &data_singleton()->jobc; + job_getrank(&rank); + id = av[1] ? ft_atoi(av[1]) : rank[0]; + if ((jlist = ft_lst_find(jobc->first_job, &id, job_cmp_id))) + { + job_run(jlist->content, 1); + return (0); + } + else if (av[1]) + SH_ERR("fg: job not found: [%i]", id); + else + SH_ERR("fg: no current job"); + return (0); +} diff --git a/42sh/src/job_control/builtin_jobs.c b/42sh/src/job_control/builtin_jobs.c new file mode 100644 index 00000000..640fbdf4 --- /dev/null +++ b/42sh/src/job_control/builtin_jobs.c @@ -0,0 +1,82 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* builtin_jobs.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/15 17:43:01 by jhalford #+# #+# */ +/* Updated: 2017/03/25 02:17:23 by wescande ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +#define JOBS_USAGE "usage: jobs [-l] [id ...]" + +t_cliopts g_jobs_opts[] = +{ + {'l', NULL, JOBS_OPT_L, 0, NULL, 0}, + {0, 0, 0, 0, 0, 0}, +}; + +static void bt_jobs_all(int opts) +{ + t_jobc *jobc; + t_list *jlist; + t_list *tmplist; + + jobc = &data_singleton()->jobc; + jlist = jobc->first_job; + tmplist = ft_lst_filter(jlist, NULL, NULL); + ft_lstsort(&tmplist, job_cmp_id); + jlist = tmplist; + while (jlist) + { + job_format(jlist->content, opts); + jlist = jlist->next; + } + ft_lstdel(&tmplist, ft_lst_cfree); +} + +static int bt_jobs_spec(char **av, int opts) +{ + t_jobc *jobc; + t_list *jlist; + t_list *lst; + int id; + + jobc = &data_singleton()->jobc; + jlist = jobc->first_job; + while (*av) + { + id = ft_atoi(*av); + if (!(lst = ft_lst_find(jlist, &id, job_cmp_id))) + { + SH_ERR("jobs: %s: no such job", *av); + return (1); + } + job_format(lst->content, opts); + av++; + } + return (0); +} + +int builtin_jobs(const char *path, char *const av[], char *const envp[]) +{ + t_data_template data; + + (void)path; + (void)envp; + if (!SH_HAS_JOBC(data_singleton()->opts)) + return (SH_ERR("jobs: %s", SH_MSG_NOJOBC)); + do_job_notification(); + ft_bzero(&data, sizeof(t_data_template)); + if (cliopts_get((char**)av, g_jobs_opts, &data)) + return (ft_perror("jobs") && SH_ERR(JOBS_USAGE)); + if (!*data.av_data) + bt_jobs_all(data.flag); + else if (bt_jobs_spec(data.av_data, data.flag)) + return (1); + return (0); +} diff --git a/42sh/src/job_control/do_job_notification.c b/42sh/src/job_control/do_job_notification.c new file mode 100644 index 00000000..4fa661df --- /dev/null +++ b/42sh/src/job_control/do_job_notification.c @@ -0,0 +1,40 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* do_job_notification.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/15 13:01:19 by jhalford #+# #+# */ +/* Updated: 2017/03/27 15:58:33 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int do_job_notification(void) +{ + t_job *j; + t_list *jlist; + t_jobc *jobc; + int ret; + + ret = 0; + job_update_status(); + jobc = &data_singleton()->jobc; + jlist = jobc->first_job; + while (jlist) + { + j = jlist->content; + jlist = jlist->next; + if (job_is_completed(j) + || (job_is_stopped(j) && !(j->attrs & JOB_NOTIFIED))) + { + ret = 1; + job_format(j, JOBS_OPT_L); + j->attrs |= JOB_NOTIFIED; + job_remove(j->id); + } + } + return (ret); +} diff --git a/42sh/src/job_control/has_running_job.c b/42sh/src/job_control/has_running_job.c new file mode 100644 index 00000000..d6a211ae --- /dev/null +++ b/42sh/src/job_control/has_running_job.c @@ -0,0 +1,31 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* has_running_job.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/21 14:27:52 by jhalford #+# #+# */ +/* Updated: 2017/03/21 14:36:47 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int has_running_job(void) +{ + t_jobc *jobc; + t_list *jlist; + t_job *j; + + jobc = &data_singleton()->jobc; + jlist = jobc->first_job; + while (jlist) + { + j = jlist->content; + if (!job_is_stopped(j)) + return (1); + jlist = jlist->next; + } + return (0); +} diff --git a/42sh/src/job_control/has_stopped_job.c b/42sh/src/job_control/has_stopped_job.c new file mode 100644 index 00000000..0260b0d0 --- /dev/null +++ b/42sh/src/job_control/has_stopped_job.c @@ -0,0 +1,31 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* has_stopped_job.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/21 14:40:36 by jhalford #+# #+# */ +/* Updated: 2017/03/21 14:41:08 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int has_stopped_job(void) +{ + t_jobc *jobc; + t_list *jlist; + t_job *j; + + jobc = &data_singleton()->jobc; + jlist = jobc->first_job; + while (jlist) + { + j = jlist->content; + if (job_is_stopped(j)) + return (1); + jlist = jlist->next; + } + return (0); +} diff --git a/42sh/src/job_control/job_addprocess.c b/42sh/src/job_control/job_addprocess.c new file mode 100644 index 00000000..e69bf241 --- /dev/null +++ b/42sh/src/job_control/job_addprocess.c @@ -0,0 +1,33 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* job_addprocess.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/13 13:54:51 by jhalford #+# #+# */ +/* Updated: 2017/03/22 19:36:16 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int job_addprocess(t_process *p) +{ + t_jobc *jobc; + t_job *job; + + jobc = &data_singleton()->jobc; + job = &data_singleton()->exec.job; + if (IS_PIPESTART(*p)) + { + job_update_id(); + job->id = jobc->current_id; + job->pgid = SH_IS_INTERACTIVE(data_singleton()->opts) ? + p->pid : getpgid(0); + ft_lstadd(&jobc->first_job, ft_lstnew(job, sizeof(*job))); + } + job = jobc->first_job->content; + ft_lsteadd(&job->first_process, ft_lstnew(p, sizeof(*p))); + return (0); +} diff --git a/42sh/src/job_control/job_cmp_id.c b/42sh/src/job_control/job_cmp_id.c new file mode 100644 index 00000000..d3f6b162 --- /dev/null +++ b/42sh/src/job_control/job_cmp_id.c @@ -0,0 +1,18 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* job_cmp_id.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/12 13:38:13 by jhalford #+# #+# */ +/* Updated: 2017/01/31 15:06:26 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int job_cmp_id(t_job *job, int *id) +{ + return (job->id - *id); +} diff --git a/42sh/src/job_control/job_format.c b/42sh/src/job_control/job_format.c new file mode 100644 index 00000000..b2822863 --- /dev/null +++ b/42sh/src/job_control/job_format.c @@ -0,0 +1,28 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* job_format.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/31 15:06:44 by jhalford #+# #+# */ +/* Updated: 2017/03/21 14:48:39 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void job_format(t_job *j, int opts) +{ + t_list *plist; + int firstp; + + job_format_head(j); + plist = j->first_process; + firstp = 1; + while (plist) + { + process_format(&plist, firstp, opts); + firstp = 0; + } +} diff --git a/42sh/src/job_control/job_format_head.c b/42sh/src/job_control/job_format_head.c new file mode 100644 index 00000000..8fe27038 --- /dev/null +++ b/42sh/src/job_control/job_format_head.c @@ -0,0 +1,24 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* job_format_head.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/09 13:10:38 by jhalford #+# #+# */ +/* Updated: 2017/03/24 18:24:43 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void job_format_head(t_job *j) +{ + char crank; + int rank[2]; + + job_getrank(&rank); + crank = j->id == rank[0] ? '+' : ' '; + crank = j->id == rank[1] ? '-' : crank; + ft_printf("{mag}[%i]%c {eoc}", j->id, crank); +} diff --git a/42sh/src/job_control/job_free.c b/42sh/src/job_control/job_free.c new file mode 100644 index 00000000..027c1676 --- /dev/null +++ b/42sh/src/job_control/job_free.c @@ -0,0 +1,23 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* job_free.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/12 12:41:11 by jhalford #+# #+# */ +/* Updated: 2017/03/20 11:39:38 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void job_free(void *content, size_t content_size) +{ + t_job *job; + + (void)content_size; + job = content; + ft_lstdel(&job->first_process, &process_free); + free(job); +} diff --git a/42sh/src/job_control/job_getprocess.c b/42sh/src/job_control/job_getprocess.c new file mode 100644 index 00000000..d1ad079c --- /dev/null +++ b/42sh/src/job_control/job_getprocess.c @@ -0,0 +1,32 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* job_getprocess.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/31 15:07:30 by jhalford #+# #+# */ +/* Updated: 2017/03/20 15:18:52 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +t_list *job_getprocess(pid_t pid) +{ + t_jobc *jobc; + t_job *j; + t_list *lst; + t_list *jlist; + + jobc = &data_singleton()->jobc; + jlist = jobc->first_job; + while (jlist) + { + j = jlist->content; + if ((lst = ft_lst_find(j->first_process, &pid, &process_cmp_pid))) + return (lst); + jlist = jlist->next; + } + return (NULL); +} diff --git a/42sh/src/job_control/job_getrank.c b/42sh/src/job_control/job_getrank.c new file mode 100644 index 00000000..319968e2 --- /dev/null +++ b/42sh/src/job_control/job_getrank.c @@ -0,0 +1,50 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* job_getrank.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/09 12:38:31 by jhalford #+# #+# */ +/* Updated: 2017/03/21 15:13:09 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static int get_jobrank(t_list *jlist, int rank) +{ + t_job *job; + t_list *head; + int ret; + + head = jlist; + ret = 0; + while (jlist && !ret) + { + job = jlist->content; + if (job_is_stopped(job)) + rank ? rank-- : (ret = job->id); + jlist = jlist->next; + } + jlist = head; + while (jlist && !ret) + { + job = jlist->content; + if (!job_is_stopped(job)) + rank ? rank-- : (ret = job->id); + jlist = jlist->next; + } + return (ret); +} + +void job_getrank(int (*rank)[2]) +{ + t_jobc *jobc; + t_list *jlist; + + jobc = &data_singleton()->jobc; + jlist = jobc->first_job; + (*rank)[0] = get_jobrank(jlist, 0); + (*rank)[1] = get_jobrank(jlist, 1); +} diff --git a/42sh/src/job_control/job_hup_all.c b/42sh/src/job_control/job_hup_all.c new file mode 100644 index 00000000..23881ff4 --- /dev/null +++ b/42sh/src/job_control/job_hup_all.c @@ -0,0 +1,32 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* job_hup_all.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/20 11:37:40 by jhalford #+# #+# */ +/* Updated: 2017/03/24 18:24:56 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void job_hup_all(void) +{ + t_jobc *jobc; + t_list *jlist; + t_job *job; + + jobc = &data_singleton()->jobc; + jlist = jobc->first_job; + if (!SH_HAS_JOBC(data_singleton()->opts)) + return ; + while (jlist) + { + job = jlist->content; + if (job->pgid != 1) + kill(-job->pgid, SIGHUP); + jlist = jlist->next; + } +} diff --git a/42sh/src/job_control/job_is_completed.c b/42sh/src/job_control/job_is_completed.c new file mode 100644 index 00000000..266cabbd --- /dev/null +++ b/42sh/src/job_control/job_is_completed.c @@ -0,0 +1,29 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* job_is_completed.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/13 15:10:20 by jhalford #+# #+# */ +/* Updated: 2017/03/20 14:37:10 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int job_is_completed(t_job *job) +{ + t_list *lst; + t_process *p; + + lst = job->first_process; + while (lst) + { + p = lst->content; + if (p->state != PROCESS_COMPLETED) + return (0); + lst = lst->next; + } + return (1); +} diff --git a/42sh/src/job_control/job_is_stopped.c b/42sh/src/job_control/job_is_stopped.c new file mode 100644 index 00000000..177eac99 --- /dev/null +++ b/42sh/src/job_control/job_is_stopped.c @@ -0,0 +1,29 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* job_is_stopped.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/13 15:06:45 by jhalford #+# #+# */ +/* Updated: 2017/03/21 14:41:16 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int job_is_stopped(t_job *job) +{ + t_list *lst; + t_process *p; + + lst = job->first_process; + while (lst) + { + p = lst->content; + if (p->state != PROCESS_COMPLETED && p->state != PROCESS_SUSPENDED) + return (0); + lst = lst->next; + } + return (1); +} diff --git a/42sh/src/job_control/job_notify_change.c b/42sh/src/job_control/job_notify_change.c new file mode 100644 index 00000000..f854d8ff --- /dev/null +++ b/42sh/src/job_control/job_notify_change.c @@ -0,0 +1,23 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* job_notify_change.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/12 15:04:03 by jhalford #+# #+# */ +/* Updated: 2017/03/21 14:23:21 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void job_notify_change(int id) +{ + t_job *job; + t_jobc *jobc; + + jobc = &data_singleton()->jobc; + job = ft_lst_find(jobc->first_job, &id, job_cmp_id)->content; + job_format(job, JOBS_OPT_L); +} diff --git a/42sh/src/job_control/job_notify_new.c b/42sh/src/job_control/job_notify_new.c new file mode 100644 index 00000000..65c56a41 --- /dev/null +++ b/42sh/src/job_control/job_notify_new.c @@ -0,0 +1,35 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* job_notify_new.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/13 14:27:01 by jhalford #+# #+# */ +/* Updated: 2017/03/20 14:26:31 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void job_notify_new(int id) +{ + t_list *plist; + t_process *p; + t_jobc *jobc; + t_job *job; + + jobc = &data_singleton()->jobc; + if (!(plist = ft_lst_find(jobc->first_job, &id, job_cmp_id))) + return ; + job = plist->content; + plist = job->first_process; + ft_printf("{mag}[%i]", job->id); + while (plist) + { + p = plist->content; + ft_printf(" %i", p->pid); + plist = plist->next; + } + ft_printf("{eoc}\n"); +} diff --git a/42sh/src/job_control/job_remove.c b/42sh/src/job_control/job_remove.c new file mode 100644 index 00000000..b8ffc169 --- /dev/null +++ b/42sh/src/job_control/job_remove.c @@ -0,0 +1,34 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* job_remove.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/15 12:51:08 by jhalford #+# #+# */ +/* Updated: 2017/03/20 20:19:55 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void job_remove(int id) +{ + t_jobc *jobc; + t_job *j; + t_list *jlist; + t_process *p; + + jobc = &data_singleton()->jobc; + if (!(jlist = ft_lst_find(jobc->first_job, &id, job_cmp_id))) + return ; + j = jlist->content; + if (job_is_completed(j)) + { + p = ft_lstlast(j->first_process)->content; + set_exitstatus(p->status, 0); + if (id < data_singleton()->jobc.current_id) + data_singleton()->jobc.current_id = id; + ft_lst_delif(&jobc->first_job, &id, job_cmp_id, job_free); + } +} diff --git a/42sh/src/job_control/job_run.c b/42sh/src/job_control/job_run.c new file mode 100644 index 00000000..517b646f --- /dev/null +++ b/42sh/src/job_control/job_run.c @@ -0,0 +1,23 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* job_run.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/09 16:54:18 by jhalford #+# #+# */ +/* Updated: 2017/03/22 19:30:10 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void job_run(t_job *job, int foreground) +{ + mark_job_as_running(job); + job_format(job, JOBS_OPT_L); + if (foreground) + put_job_in_foreground(job, 1); + else + put_job_in_background(job, 1); +} diff --git a/42sh/src/job_control/job_update_id.c b/42sh/src/job_control/job_update_id.c new file mode 100644 index 00000000..8b423e52 --- /dev/null +++ b/42sh/src/job_control/job_update_id.c @@ -0,0 +1,26 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* job_update_id.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/12 13:33:08 by jhalford #+# #+# */ +/* Updated: 2017/03/03 18:18:29 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void job_update_id(void) +{ + int *id; + t_jobc *jobc; + t_list *start; + + jobc = &data_singleton()->jobc; + id = &jobc->current_id; + start = jobc->first_job; + while (ft_lst_find(start, id, job_cmp_id)) + *id += 1; +} diff --git a/42sh/src/job_control/job_update_status.c b/42sh/src/job_control/job_update_status.c new file mode 100644 index 00000000..8b00a02b --- /dev/null +++ b/42sh/src/job_control/job_update_status.c @@ -0,0 +1,28 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* job_update_status.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/15 12:56:11 by jhalford #+# #+# */ +/* Updated: 2017/03/27 03:17:54 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void job_update_status(void) +{ + int status; + pid_t pid; + + while (1) + { + if ((pid = waitpid(WAIT_ANY, &status, WUNTRACED | WNOHANG)) == -1 + && errno != ECHILD) + SH_ERR("waitpid(): %s", strerror(errno)); + if (pid <= 1 || mark_process_status(pid, status)) + break ; + } +} diff --git a/42sh/src/job_control/job_wait.c b/42sh/src/job_control/job_wait.c new file mode 100644 index 00000000..1ccdfbab --- /dev/null +++ b/42sh/src/job_control/job_wait.c @@ -0,0 +1,38 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* job_wait.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/15 11:49:05 by jhalford #+# #+# */ +/* Updated: 2017/03/22 17:48:54 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int job_wait(int id) +{ + pid_t pid; + t_job *j; + t_list *jlist; + t_jobc *jobc; + int status; + + jobc = &data_singleton()->jobc; + if (!(jlist = ft_lst_find(jobc->first_job, &id, job_cmp_id))) + return (-1); + j = jlist->content; + while (1) + { + if ((pid = waitpid(-j->pgid, &status, WUNTRACED)) == -1 + && errno != ECHILD) + SH_ERR("waitpid(): %s", strerror(errno)); + if (pid <= 1 || mark_process_status(pid, status) + || job_is_stopped(j) + || job_is_completed(j)) + break ; + } + return (0); +} diff --git a/42sh/src/job_control/jobc_destroy.c b/42sh/src/job_control/jobc_destroy.c new file mode 100644 index 00000000..068d1238 --- /dev/null +++ b/42sh/src/job_control/jobc_destroy.c @@ -0,0 +1,20 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* jobc_destroy.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/27 03:09:41 by jhalford #+# #+# */ +/* Updated: 2017/03/27 15:59:29 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int jobc_destroy(t_jobc *jobc) +{ + if (jobc) + ft_lstdel(&jobc->first_job, job_free); + return (0); +} diff --git a/42sh/src/job_control/jobc_init.c b/42sh/src/job_control/jobc_init.c new file mode 100644 index 00000000..fd8fc134 --- /dev/null +++ b/42sh/src/job_control/jobc_init.c @@ -0,0 +1,20 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* jobc_init.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/27 15:59:03 by jhalford #+# #+# */ +/* Updated: 2017/03/27 16:01:41 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int jobc_init(t_jobc *jobc) +{ + jobc->first_job = NULL; + jobc->current_id = 1; + return (0); +} diff --git a/42sh/src/job_control/mark_job_as_running.c b/42sh/src/job_control/mark_job_as_running.c new file mode 100644 index 00000000..0cf46b23 --- /dev/null +++ b/42sh/src/job_control/mark_job_as_running.c @@ -0,0 +1,29 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* mark_job_as_running.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/08 14:40:40 by jhalford #+# #+# */ +/* Updated: 2017/03/20 11:33:55 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void mark_job_as_running(t_job *j) +{ + t_list *plist; + t_process *p; + + plist = j->first_process; + while (plist) + { + p = plist->content; + if (p->state == PROCESS_SUSPENDED) + p->state = PROCESS_CONTINUED; + plist = plist->next; + } + j->attrs &= ~JOB_NOTIFIED; +} diff --git a/42sh/src/job_control/pprint_brace.c b/42sh/src/job_control/pprint_brace.c new file mode 100644 index 00000000..5d28d782 --- /dev/null +++ b/42sh/src/job_control/pprint_brace.c @@ -0,0 +1,20 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* pprint_brace.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/13 20:42:06 by jhalford #+# #+# */ +/* Updated: 2017/03/13 20:42:26 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int pprint_brace(t_process *p) +{ + (void)p; + ft_putstr("BRACE GROUP"); + return (0); +} diff --git a/42sh/src/job_control/pprint_case.c b/42sh/src/job_control/pprint_case.c new file mode 100644 index 00000000..9ac8e632 --- /dev/null +++ b/42sh/src/job_control/pprint_case.c @@ -0,0 +1,20 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* pprint_case.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/16 16:58:56 by jhalford #+# #+# */ +/* Updated: 2017/03/16 16:58:56 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int pprint_case(t_process *p) +{ + (void)p; + ft_putstr("CASE GROUP"); + return (0); +} diff --git a/42sh/src/job_control/pprint_cmd.c b/42sh/src/job_control/pprint_cmd.c new file mode 100644 index 00000000..1e2b36af --- /dev/null +++ b/42sh/src/job_control/pprint_cmd.c @@ -0,0 +1,19 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* pprint_cmd.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/16 16:55:30 by jhalford #+# #+# */ +/* Updated: 2017/03/16 16:55:34 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int pprint_cmd(t_process *p) +{ + ft_sstrprint(p->data.cmd.av, ' '); + return (0); +} diff --git a/42sh/src/job_control/pprint_for.c b/42sh/src/job_control/pprint_for.c new file mode 100644 index 00000000..c81b18fd --- /dev/null +++ b/42sh/src/job_control/pprint_for.c @@ -0,0 +1,20 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* pprint_for.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/16 16:55:26 by jhalford #+# #+# */ +/* Updated: 2017/03/16 16:55:27 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int pprint_for(t_process *p) +{ + (void)p; + ft_putstr("FOR GROUP"); + return (0); +} diff --git a/42sh/src/job_control/pprint_function.c b/42sh/src/job_control/pprint_function.c new file mode 100644 index 00000000..755c7690 --- /dev/null +++ b/42sh/src/job_control/pprint_function.c @@ -0,0 +1,20 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* pprint_function.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/16 16:53:36 by jhalford #+# #+# */ +/* Updated: 2017/03/16 16:53:36 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int pprint_function(t_process *p) +{ + (void)p; + ft_putstr("FUNCTION GROUP"); + return (0); +} diff --git a/42sh/src/job_control/pprint_if.c b/42sh/src/job_control/pprint_if.c new file mode 100644 index 00000000..eb6dc692 --- /dev/null +++ b/42sh/src/job_control/pprint_if.c @@ -0,0 +1,20 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* pprint_if.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/16 16:53:20 by jhalford #+# #+# */ +/* Updated: 2017/03/16 16:53:21 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int pprint_if(t_process *p) +{ + (void)p; + ft_putstr("IF GROUP"); + return (0); +} diff --git a/42sh/src/job_control/pprint_subshell.c b/42sh/src/job_control/pprint_subshell.c new file mode 100644 index 00000000..bd0737e1 --- /dev/null +++ b/42sh/src/job_control/pprint_subshell.c @@ -0,0 +1,20 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* pprint_subshell.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/16 16:53:59 by jhalford #+# #+# */ +/* Updated: 2017/03/16 16:54:00 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int pprint_subshell(t_process *p) +{ + (void)p; + ft_putstr("SUBSHELL GROUP"); + return (0); +} diff --git a/42sh/src/job_control/pprint_until.c b/42sh/src/job_control/pprint_until.c new file mode 100644 index 00000000..cf23fa29 --- /dev/null +++ b/42sh/src/job_control/pprint_until.c @@ -0,0 +1,20 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* pprint_until.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/16 16:53:43 by jhalford #+# #+# */ +/* Updated: 2017/03/16 16:53:43 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int pprint_until(t_process *p) +{ + (void)p; + ft_putstr("UNTIL GROUP"); + return (0); +} diff --git a/42sh/src/job_control/pprint_while.c b/42sh/src/job_control/pprint_while.c new file mode 100644 index 00000000..6039b9d2 --- /dev/null +++ b/42sh/src/job_control/pprint_while.c @@ -0,0 +1,20 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* pprint_while.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/16 16:53:29 by jhalford #+# #+# */ +/* Updated: 2017/03/16 16:53:30 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int pprint_while(t_process *p) +{ + (void)p; + ft_putstr("WHILE GROUP"); + return (0); +} diff --git a/42sh/src/job_control/process_cmp_pid.c b/42sh/src/job_control/process_cmp_pid.c new file mode 100644 index 00000000..7683e116 --- /dev/null +++ b/42sh/src/job_control/process_cmp_pid.c @@ -0,0 +1,18 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* process_cmp_pid.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/12 13:00:21 by jhalford #+# #+# */ +/* Updated: 2017/01/31 15:06:21 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int process_cmp_pid(t_process *p, pid_t *pid) +{ + return (p->pid - *pid); +} diff --git a/42sh/src/job_control/process_format.c b/42sh/src/job_control/process_format.c new file mode 100644 index 00000000..19e9e66a --- /dev/null +++ b/42sh/src/job_control/process_format.c @@ -0,0 +1,110 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* process_format.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/09 13:05:55 by jhalford #+# #+# */ +/* Updated: 2017/03/22 16:40:13 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static int redirection_print(t_redir *redir) +{ + char symbol[3]; + + if (redir->type == TK_LESS) + ft_strcpy(symbol, "<"); + else if (redir->type == TK_GREAT) + ft_strcpy(symbol, ">"); + else if (redir->type == TK_DLESS) + ft_strcpy(symbol, "<<"); + else if (redir->type == TK_DGREAT) + ft_strcpy(symbol, ">>"); + else if (redir->type == TK_LESSAND) + ft_strcpy(symbol, "<&"); + else if (redir->type == TK_GREATAND) + ft_strcpy(symbol, ">&"); + ft_printf(" %i%s%s", redir->n, symbol, redir->word); + return (0); +} + +static void process_format_state(t_process *p) +{ + char *statestr; + + statestr = NULL; + if (p->state == PROCESS_RUNNING) + ft_asprintf(&statestr, "running"); + else if (p->state == PROCESS_SUSPENDED) + ft_asprintf(&statestr, "suspended"); + else if (p->state == PROCESS_CONTINUED) + { + ft_asprintf(&statestr, "continued"); + p->state = PROCESS_RUNNING; + } + else if (p->state == PROCESS_COMPLETED) + { + if (WIFSIGNALED(p->status)) + ft_asprintf(&statestr, strsignal(WTERMSIG(p->status))); + else if (p->status == 0) + ft_asprintf(&statestr, "done"); + else + ft_asprintf(&statestr, "%s %i", "exit", WEXITSTATUS(p->status)); + } + ft_printf("%-*s\t", 12, statestr); + ft_strdel(&statestr); +} + +static void process_format_com_long(t_list **plist) +{ + t_process *p; + + p = (*plist)->content; + if (p->map.print) + (p->map.print)(p); + ft_lstiter(p->redirs, redirection_print); + if ((*plist)->next) + ft_putstr(" |"); + (*plist) = (*plist)->next; +} + +static void process_format_com_short(t_list **plist, t_flag state) +{ + t_process *p; + + while (*plist) + { + p = (*plist)->content; + if (p->state != state) + break ; + if (p->state == PROCESS_CONTINUED) + p->state = PROCESS_RUNNING; + if (p->map.print) + (p->map.print)(p); + ft_lstiter(p->redirs, redirection_print); + if ((*plist)->next) + ft_putstr(" | "); + (*plist) = (*plist)->next; + } +} + +void process_format(t_list **plist, int firstp, int opts) +{ + t_process *p; + + p = (*plist)->content; + if (!firstp) + ft_putstr(" "); + if (opts & JOBS_OPT_L) + ft_printf("%i ", p->pid); + process_format_state(p); + if (opts & JOBS_OPT_L) + process_format_com_long(plist); + else + process_format_com_short(plist, p->state); + ft_putchar('\n'); +} diff --git a/42sh/src/job_control/process_free.c b/42sh/src/job_control/process_free.c new file mode 100644 index 00000000..1251fbc7 --- /dev/null +++ b/42sh/src/job_control/process_free.c @@ -0,0 +1,26 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* process_free.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/12 12:41:11 by jhalford #+# #+# */ +/* Updated: 2017/03/22 18:15:48 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void process_free(void *content, size_t content_size) +{ + t_process *p; + + p = content; + (void)content_size; + if (p->map.free) + (p->map.free)(p); + ft_lstdel(&p->redirs, redir_free); + if (content_size) + free(p); +} diff --git a/42sh/src/job_control/put_job_in_background.c b/42sh/src/job_control/put_job_in_background.c new file mode 100644 index 00000000..ae75068d --- /dev/null +++ b/42sh/src/job_control/put_job_in_background.c @@ -0,0 +1,21 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* put_job_in_background.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/13 15:03:29 by jhalford #+# #+# */ +/* Updated: 2017/03/24 17:24:46 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int put_job_in_background(t_job *j, int cont) +{ + if (cont) + if (kill(-j->pgid, SIGCONT) < 0) + SH_ERR("kill(): %s", strerror(errno)); + return (0); +} diff --git a/42sh/src/job_control/put_job_in_foreground.c b/42sh/src/job_control/put_job_in_foreground.c new file mode 100644 index 00000000..aa28235c --- /dev/null +++ b/42sh/src/job_control/put_job_in_foreground.c @@ -0,0 +1,39 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* put_job_in_foreground.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/13 14:58:36 by jhalford #+# #+# */ +/* Updated: 2017/03/24 23:27:51 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +#define FGERR_0 "kill(SIGCONT) failed" + +int put_job_in_foreground(t_job *j, int cont) +{ + t_jobc *jobc; + + jobc = &data_singleton()->jobc; + if (SH_IS_INTERACTIVE(data_singleton()->opts)) + tcsetpgrp(STDIN, j->pgid); + if (cont) + { + tcsetattr(STDIN, TCSADRAIN, &j->tmodes); + if (kill(-j->pgid, SIGCONT) < 0) + SH_ERR(FGERR_0); + } + job_wait(j->id); + if (SH_IS_INTERACTIVE(data_singleton()->opts)) + { + tcsetpgrp(STDIN, jobc->shell_pgid); + tcgetattr(STDIN, &j->tmodes); + tcsetattr(STDIN, TCSADRAIN, &jobc->shell_tmodes); + } + job_remove(j->id); + return (0); +} diff --git a/42sh/src/job_control/sigchld_handler.c b/42sh/src/job_control/sigchld_handler.c new file mode 100644 index 00000000..d7ddade0 --- /dev/null +++ b/42sh/src/job_control/sigchld_handler.c @@ -0,0 +1,18 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* sigchld_handler.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/10 17:37:56 by jhalford #+# #+# */ +/* Updated: 2017/03/20 10:20:44 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void sigchld_handler(int signo) +{ + (void)signo; +} diff --git a/42sh/src/job_control/sigint_handler.c b/42sh/src/job_control/sigint_handler.c new file mode 100644 index 00000000..cdb16537 --- /dev/null +++ b/42sh/src/job_control/sigint_handler.c @@ -0,0 +1,19 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* sigint_handler.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/10 15:14:47 by jhalford #+# #+# */ +/* Updated: 2017/03/24 17:24:18 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void sigint_handler(int signo) +{ + (void)signo; + set_exitstatus(1, 1); +} diff --git a/42sh/src/job_control/sigtstp_handler.c b/42sh/src/job_control/sigtstp_handler.c new file mode 100644 index 00000000..d771e8a3 --- /dev/null +++ b/42sh/src/job_control/sigtstp_handler.c @@ -0,0 +1,18 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* sigtstp_handler.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/10 15:14:53 by jhalford #+# #+# */ +/* Updated: 2017/03/16 16:52:46 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void sigtstp_handler(int signo) +{ + (void)signo; +} diff --git a/42sh/src/job_control/sigttin_handler.c b/42sh/src/job_control/sigttin_handler.c new file mode 100644 index 00000000..21c01466 --- /dev/null +++ b/42sh/src/job_control/sigttin_handler.c @@ -0,0 +1,18 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* sigttin_handler.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/10 15:14:53 by jhalford #+# #+# */ +/* Updated: 2017/03/24 17:24:13 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void sigttin_handler(int signo) +{ + (void)signo; +} diff --git a/42sh/src/job_control/sigttou_handler.c b/42sh/src/job_control/sigttou_handler.c new file mode 100644 index 00000000..501e4b96 --- /dev/null +++ b/42sh/src/job_control/sigttou_handler.c @@ -0,0 +1,18 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* sigttou_handler.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/10 15:14:53 by jhalford #+# #+# */ +/* Updated: 2017/03/24 17:23:18 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void sigttou_handler(int signo) +{ + (void)signo; +} diff --git a/42sh/src/lexer/do_lexer_routine.c b/42sh/src/lexer/do_lexer_routine.c new file mode 100644 index 00000000..a02f5887 --- /dev/null +++ b/42sh/src/lexer/do_lexer_routine.c @@ -0,0 +1,42 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* do_lexer_routine.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/19 14:24:38 by wescande #+# #+# */ +/* Updated: 2017/03/22 16:37:46 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int do_lexer_routine(t_list **token, char *stream) +{ + t_list *ltoken; + t_data *data; + static t_type last; + + data = data_singleton(); + if (data->lexer.state == HEREDOC) + ft_strappend(&data->lexer.str, (char[]){'\n', 0}); + if (data->parser.state == UNDEFINED && !isrw_delim(last)) + ft_strappend(&data->lexer.str, (char[]){';', 0}); + else if (data->parser.state == UNDEFINED && last != 0) + ft_strappend(&data->lexer.str, (char[]){' ', 0}); + if (data->lexer.state == HEREDOC || (data->parser.state == UNDEFINED + && last != 0)) + data->lexer.pos++; + ft_strappend(&data->lexer.str, stream); + if (get_lexer_stack(data->lexer) == BACKSLASH) + pop(&data->lexer.stack); + ltoken = ft_lstlast(*token); + if (lexer_lex(*token ? <oken : token, &data->lexer) < 0) + exit(1); + if ((get_lexer_stack(data->lexer) > 2) || (get_reserved_words(*token))) + return (1); + keep_last_type(&last, *token); + data->lexer.state = DEFAULT; + 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..8e04ad7a --- /dev/null +++ b/42sh/src/lexer/get_lexer_stack.c @@ -0,0 +1,18 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* get_lexer_stack.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/03 17:39:45 by jhalford #+# #+# */ +/* Updated: 2017/03/24 20:04:00 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int get_lexer_stack(t_lexer lexer) +{ + return (lexer.stack ? *(int*)lexer.stack->content : 0); +} diff --git a/42sh/src/lexer/get_lexer_stack2.c b/42sh/src/lexer/get_lexer_stack2.c new file mode 100644 index 00000000..ff1c56d6 --- /dev/null +++ b/42sh/src/lexer/get_lexer_stack2.c @@ -0,0 +1,20 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* get_lexer_stack2.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/23 15:15:46 by jhalford #+# #+# */ +/* Updated: 2017/03/23 16:12:26 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int get_lexer_stack2(t_lexer lexer) +{ + if (!(lexer.stack && lexer.stack->next)) + return (0); + return (*(int*)lexer.stack->next->content); +} diff --git a/42sh/src/lexer/get_reserved_words.c b/42sh/src/lexer/get_reserved_words.c new file mode 100644 index 00000000..382a6764 --- /dev/null +++ b/42sh/src/lexer/get_reserved_words.c @@ -0,0 +1,96 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* get_reserved_words.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ariard +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/26 00:07:05 by ariard #+# #+# */ +/* Updated: 2017/03/29 15:07:16 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static t_rvwords g_rvwords[] = +{ + {"while", TK_WHILE}, + {"done", TK_DONE}, + {"do", TK_DO}, + {"if", TK_IF}, + {"then", TK_THEN}, + {"fi", TK_FI}, + {"elif", TK_ELIF}, + {"else", TK_ELSE}, + {"until", TK_UNTIL}, + {"case", TK_CASE}, + {"esac", TK_ESAC}, + {"for", TK_FOR}, + {"null", 0}, +}; + +static int recognization_rvwords(t_token *pv_tk, t_token *at_tk) +{ + return (!pv_tk || (pv_tk->type == TK_NEWLINE || pv_tk->type == TK_AMP + || pv_tk->type == TK_SEMI || pv_tk->type == TK_PIPE + || pv_tk->type == TK_WHILE || pv_tk->type == TK_DONE + || pv_tk->type == TK_DO || pv_tk->type == TK_IF + || pv_tk->type == TK_FI || pv_tk->type == TK_THEN + || pv_tk->type == TK_ELIF || pv_tk->type == TK_ELSE + || pv_tk->type == TK_DSEMI || pv_tk->type == TK_PAREN_OPEN + || pv_tk->type == TK_LBRACE || pv_tk->type == TK_UNTIL) + || pv_tk->type == TK_PAREN_CLOSE || pv_tk->type == TK_AND_IF + || pv_tk->type == TK_OR_IF + || (pv_tk->type == TK_PAREN_CLOSE && at_tk->type == TK_PAREN_OPEN)); +} + +static int match_words(t_token *token) +{ + int i; + + if (token->type == TK_WORD) + { + i = 0; + while (g_rvwords[i].type) + { + if (ft_strcmp(token->data, g_rvwords[i].word) == 0) + token->type = g_rvwords[i].type; + i++; + } + } + return (0); +} + +static int is_bang(t_token *token) +{ + return (token && token->type != TK_SEMI && token->type != TK_NEWLINE + && token->type != TK_AMP); +} + +int get_reserved_words(t_list *temp) +{ + t_token *token; + t_token *pv_tk; + t_token *ante_token; + + pv_tk = NULL; + ante_token = NULL; + while (temp) + { + token = temp->content; + if (recognization_rvwords(pv_tk, ante_token)) + match_words(token); + if (token && token->type == TK_BANG && is_bang(pv_tk)) + token->type = TK_WORD; + if (ante_token && (ante_token->type == TK_CASE + || ante_token->type == TK_FOR) + && ft_strncmp(token->data, "in", 2) == 0) + token->type = TK_IN; + if (pv_tk && pv_tk->type == TK_FOR && token->type == TK_WORD) + token->type = TK_NAME; + ante_token = pv_tk; + pv_tk = token; + temp = temp->next; + } + return (0); +} diff --git a/42sh/src/lexer/get_state_global.c b/42sh/src/lexer/get_state_global.c new file mode 100644 index 00000000..dc7bedc0 --- /dev/null +++ b/42sh/src/lexer/get_state_global.c @@ -0,0 +1,41 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* get_state_global.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/09 20:39:06 by jhalford #+# #+# */ +/* Updated: 2017/03/27 19:56:59 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +t_lexstate get_state_global(t_lexer *lexer) +{ + char c; + char cn; + char cl; + int ret; + + c = lexer->str[lexer->pos]; + cn = lexer->str[lexer->pos + 1]; + cl = lexer->pos ? lexer->str[lexer->pos - 1] : 0; + ret = 0; + if ((ft_is_delim(c) && (ret = DELIM)) + || ((c == '&' || c == ';' || c == '|' || c == '!') && (ret = SEP)) + || ((c == '\\') && (ret = BACKSLASH)) + || ((c == '\n') && (ret = NEWLINE)) + || ((c == '\'') && (ret = QUOTE)) + || ((c == '\"') && (ret = DQUOTE)) + || ((c == '`') && (ret = BQUOTE)) + || ((c == '(' || c == ')') && (ret = PAREN)) + || (((c == '{' && (cn == ' ' || cn == 0)) + || (c == '}' && (cl == ' ' || cl == 0))) && (ret = CURLY_BRACKETS)) + || ((c == 0) && (ret = END))) + { + ; + } + return (ret); +} diff --git a/42sh/src/lexer/get_state_redir.c b/42sh/src/lexer/get_state_redir.c new file mode 100644 index 00000000..997dde9a --- /dev/null +++ b/42sh/src/lexer/get_state_redir.c @@ -0,0 +1,25 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* get_state_redir.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/09 20:37:28 by jhalford #+# #+# */ +/* Updated: 2017/03/16 19:00:44 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +t_lexstate get_state_redir(t_lexer *lexer) +{ + char c; + + c = lexer->str[lexer->pos]; + if (c == '>') + return (GREAT); + else if (c == '<') + return (LESS); + return (0); +} diff --git a/42sh/src/lexer/insert_newline.c b/42sh/src/lexer/insert_newline.c new file mode 100644 index 00000000..d91048e4 --- /dev/null +++ b/42sh/src/lexer/insert_newline.c @@ -0,0 +1,24 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* insert_newline.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ariard +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/21 21:05:23 by ariard #+# #+# */ +/* Updated: 2017/03/16 14:41:14 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int insert_newline(t_list **alst) +{ + t_token *token; + + token = token_init(); + token->type = TK_NEWLINE; + ft_lsteadd(alst, ft_lstnew(token, sizeof(*token))); + free(token); + return (0); +} diff --git a/42sh/src/lexer/isrw_delim.c b/42sh/src/lexer/isrw_delim.c new file mode 100644 index 00000000..5d9212a5 --- /dev/null +++ b/42sh/src/lexer/isrw_delim.c @@ -0,0 +1,26 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* isrw_delim.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ariard +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/20 19:12:50 by ariard #+# #+# */ +/* Updated: 2017/03/24 14:49:17 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int isrw_delim(t_type type) +{ + return (type == TK_NEWLINE || type == TK_AMP + || type == TK_SEMI || type == TK_PIPE + || type == TK_WHILE || type == TK_UNTIL + || type == TK_DO || type == TK_IF + || type == TK_THEN || type == TK_RBRACE + || type == TK_ELIF || type == TK_ELSE + || type == TK_DSEMI || type == TK_PAREN_CLOSE + || type == TK_PAREN_OPEN || type == TK_LBRACE + || type == TK_IN || type == 0); +} diff --git a/42sh/src/lexer/keep_last_type.c b/42sh/src/lexer/keep_last_type.c new file mode 100644 index 00000000..9e881e97 --- /dev/null +++ b/42sh/src/lexer/keep_last_type.c @@ -0,0 +1,22 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* keep_last_type.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ariard +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/20 16:15:34 by ariard #+# #+# */ +/* Updated: 2017/03/22 16:38:19 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int keep_last_type(t_type *last, t_list *token) +{ + t_list *tmp; + + if (!(tmp = ft_lstlast(token))) + return ((*last = 0)); + return (*last = ((t_token *)tmp->content)->type); +} diff --git a/42sh/src/lexer/lexer_backslash.c b/42sh/src/lexer/lexer_backslash.c new file mode 100644 index 00000000..9ce1660e --- /dev/null +++ b/42sh/src/lexer/lexer_backslash.c @@ -0,0 +1,32 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* lexer_backslash.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/03 11:56:49 by jhalford #+# #+# */ +/* Updated: 2017/03/27 20:23:24 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int lexer_backslash(t_list **alst, t_lexer *lexer) +{ + t_token *token; + + token = (*alst)->content; + lexer->state = DEFAULT; + if (lexer->str[lexer->pos + 1] == 0) + { + lexer->str[lexer->pos] = 0; + push(&lexer->stack, BACKSLASH); + return (0); + } + token->type = token->type ? token->type : TK_WORD; + lexer->pos++; + 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..ff9fff8c --- /dev/null +++ b/42sh/src/lexer/lexer_bquote.c @@ -0,0 +1,41 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* lexer_bquote.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/09 22:03:48 by jhalford #+# #+# */ +/* Updated: 2017/03/24 17:02:40 by wescande ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int lexer_bquote(t_list **alst, t_lexer *lexer) +{ + t_token *token; + int back; + + token = (*alst)->content; + token->type = token->type ? token->type : TK_WORD; + back = 0; + if (lexer->str[lexer->pos] == '`') + { + if (get_lexer_stack(*lexer) != BQUOTE) + push(&lexer->stack, lexer->state); + else + lexer->state = pop(&lexer->stack) && + get_lexer_stack(*lexer) == DQUOTE ? DQUOTE : DEFAULT; + } + else if (lexer->str[lexer->pos] == '\\' && (back = 1)) + { + lexer->pos++; + if (lexer->str[lexer->pos] == 0) + return (push(&lexer->stack, BACKSLASH) ? 0 : 0); + } + token_append(token, lexer, back || token->type == TK_ASSIGNMENT_WORD + || get_lexer_stack2(*lexer) == DQUOTE, back); + lexer->pos++; + return (lexer_lex(alst, lexer)); +} diff --git a/42sh/src/lexer/lexer_curly_braces.c b/42sh/src/lexer/lexer_curly_braces.c new file mode 100644 index 00000000..8648c30d --- /dev/null +++ b/42sh/src/lexer/lexer_curly_braces.c @@ -0,0 +1,36 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* lexer_curly_braces.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/05 16:29:35 by jhalford #+# #+# */ +/* Updated: 2017/03/22 18:15:28 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int lexer_curly_braces(t_list **alst, t_lexer *lexer) +{ + t_token *token; + + token = (*alst)->content; + if (token->type) + lexer_lex(&(*alst)->next, lexer); + if (lexer->str[lexer->pos] == '{') + { + token->type = TK_LBRACE; + push(&lexer->stack, CURLY_BRACKETS); + } + else + { + token->type = TK_RBRACE; + if (get_lexer_stack(*lexer) == CURLY_BRACKETS) + pop(&lexer->stack); + } + lexer->pos++; + lexer->state = DEFAULT; + return (lexer_lex(&(*alst)->next, lexer)); +} diff --git a/42sh/src/lexer/lexer_default.c b/42sh/src/lexer/lexer_default.c new file mode 100644 index 00000000..7e6c2184 --- /dev/null +++ b/42sh/src/lexer/lexer_default.c @@ -0,0 +1,29 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* lexer_default.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/28 18:36:21 by jhalford #+# #+# */ +/* Updated: 2017/03/17 19:28:09 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int lexer_default(t_list **alst, t_lexer *lexer) +{ + t_token *token; + char c; + + 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_WORD; + return (lexer_lex(alst, lexer)); +} diff --git a/42sh/src/lexer/lexer_delim.c b/42sh/src/lexer/lexer_delim.c new file mode 100644 index 00000000..260dfc1c --- /dev/null +++ b/42sh/src/lexer/lexer_delim.c @@ -0,0 +1,28 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* lexer_delim.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/03 11:58:44 by jhalford #+# #+# */ +/* Updated: 2017/03/21 13:33:58 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int lexer_delim(t_list **alst, t_lexer *lexer) +{ + t_token *token; + + token = (*alst)->content; + while (ft_is_delim(lexer->str[lexer->pos])) + lexer->pos++; + lexer->state = DEFAULT; + if (token->type) + return (lexer_lex(&(*alst)->next, lexer)); + 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_destroy.c b/42sh/src/lexer/lexer_destroy.c new file mode 100644 index 00000000..feb14ed2 --- /dev/null +++ b/42sh/src/lexer/lexer_destroy.c @@ -0,0 +1,22 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* lexer_destroy.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ariard +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/16 20:25:08 by ariard #+# #+# */ +/* Updated: 2017/03/24 17:15:18 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void lexer_destroy(t_lexer *lexer) +{ + ft_strdel(&lexer->str); + lexer->pos = 0; + lexer->state = 0; + ft_lstdel(&lexer->stack, ft_lst_cfree); + lexer->heredoc_stack = NULL; +} diff --git a/42sh/src/lexer/lexer_dquote.c b/42sh/src/lexer/lexer_dquote.c new file mode 100644 index 00000000..9f85136c --- /dev/null +++ b/42sh/src/lexer/lexer_dquote.c @@ -0,0 +1,45 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* lexer_dquote.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/28 18:36:58 by jhalford #+# #+# */ +/* Updated: 2017/03/28 19:55:03 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static int is_spec_dquote_esc(char c) +{ + return (c == '"' || c == '$' || c == '`' + || c == '\\' || c == '!'); +} + +int lexer_dquote(t_list **alst, t_lexer *lexer) +{ + t_token *token; + + token = (*alst)->content; + token->type = token->type ? token->type : TK_WORD; + if (lexer->str[lexer->pos] == '"') + get_lexer_stack(*lexer) == DQUOTE && (lexer->state = WORD) ? + pop(&lexer->stack) : push(&lexer->stack, DQUOTE) && 0; + else if (lexer->str[lexer->pos] == '\\') + { + if (lexer->str[++lexer->pos] == 0) + return (push(&lexer->stack, BACKSLASH) ? 0 : 0); + else if (is_spec_dquote_esc(lexer->str[lexer->pos])) + token_append(token, lexer, 1, 1); + else if (--lexer->pos || 1) + token_append(token, lexer, 1, 1); + } + else if (lexer->str[lexer->pos] == '`' && (lexer->state = BQUOTE)) + return (lexer_lex(alst, lexer)); + else + 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..fc6f2844 --- /dev/null +++ b/42sh/src/lexer/lexer_end.c @@ -0,0 +1,33 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* lexer_end.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/05 16:58:24 by jhalford #+# #+# */ +/* Updated: 2017/03/21 13:16:57 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int lexer_end(t_list **alst, t_lexer *lexer) +{ + t_token *token; + + if (lexer->str[lexer->pos] == '#') + while (lexer->str[++lexer->pos]) + ; + if (*alst && (lexer->state == QUOTE + || lexer->state == DQUOTE + || lexer->state == BQUOTE)) + { + token = (*alst)->content; + ft_strappend(&lexer->str, (char[]){'\n', 0}); + token_append_char(token, '\n', 1, 0); + lexer->pos++; + return (0); + } + return (0); +} diff --git a/42sh/src/lexer/lexer_great.c b/42sh/src/lexer/lexer_great.c new file mode 100644 index 00000000..404abf86 --- /dev/null +++ b/42sh/src/lexer/lexer_great.c @@ -0,0 +1,40 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* lexer_great.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/03 12:06:35 by jhalford #+# #+# */ +/* Updated: 2017/03/16 19:01:02 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int lexer_great(t_list **alst, t_lexer *lexer) +{ + t_token *token; + + token = (*alst)->content; + if (token->type) + return (lexer_lex(&(*alst)->next, lexer)); + lexer->pos++; + if (lexer->str[lexer->pos] == '&') + { + token->type = TK_GREATAND; + lexer->pos++; + lexer->state = DEFAULT; + return (lexer_lex(&(*alst)->next, lexer)); + } + if (lexer->str[lexer->pos] == '>') + { + token->type = TK_DGREAT; + lexer->pos++; + lexer->state = DEFAULT; + return (lexer_lex(&(*alst)->next, lexer)); + } + token->type = TK_GREAT; + lexer->state = DEFAULT; + return (lexer_lex(&(*alst)->next, lexer)); +} diff --git a/42sh/src/lexer/lexer_heredoc.c b/42sh/src/lexer/lexer_heredoc.c new file mode 100644 index 00000000..67cfd884 --- /dev/null +++ b/42sh/src/lexer/lexer_heredoc.c @@ -0,0 +1,25 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* lexer_heredoc.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/08 15:51:17 by jhalford #+# #+# */ +/* Updated: 2017/03/10 13:27:32 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int lexer_heredoc(t_list **alst, t_lexer *lexer) +{ + t_token *token; + + token = (*alst)->content; + token->type = HEREDOCDATA; + while (lexer->str[lexer->pos]) + if (token_append_char(token, lexer->str[lexer->pos++], 0, 0)) + return (1); + return (0); +} diff --git a/42sh/src/lexer/lexer_init.c b/42sh/src/lexer/lexer_init.c new file mode 100644 index 00000000..261bf644 --- /dev/null +++ b/42sh/src/lexer/lexer_init.c @@ -0,0 +1,22 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* lexer_init.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ariard +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/21 16:14:08 by ariard #+# #+# */ +/* Updated: 2017/03/16 17:57:47 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.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 new file mode 100644 index 00000000..e5d28d0e --- /dev/null +++ b/42sh/src/lexer/lexer_less.c @@ -0,0 +1,40 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* lexer_less.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/03 12:06:53 by jhalford #+# #+# */ +/* Updated: 2017/03/16 19:00:51 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int lexer_less(t_list **alst, t_lexer *lexer) +{ + t_token *token; + + token = (*alst)->content; + if (token->type) + return (lexer_lex(&(*alst)->next, lexer)); + lexer->pos++; + if (lexer->str[lexer->pos] == '&') + { + token->type = TK_LESSAND; + lexer->pos++; + lexer->state = DEFAULT; + return (lexer_lex(&(*alst)->next, lexer)); + } + if (lexer->str[lexer->pos] == '<') + { + token->type = TK_DLESS; + lexer->pos++; + lexer->state = DEFAULT; + return (lexer_lex(&(*alst)->next, lexer)); + } + token->type = TK_LESS; + lexer->state = DEFAULT; + return (lexer_lex(&(*alst)->next, lexer)); +} diff --git a/42sh/src/lexer/lexer_lex.c b/42sh/src/lexer/lexer_lex.c new file mode 100644 index 00000000..c098ff20 --- /dev/null +++ b/42sh/src/lexer/lexer_lex.c @@ -0,0 +1,58 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* lexer_lex.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/09 17:08:51 by jhalford #+# #+# */ +/* Updated: 2017/03/27 19:29:37 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int (*g_lexer[])(t_list **alst, t_lexer *lexer) = +{ + &lexer_default, + &lexer_paren, + &lexer_heredoc, + &lexer_newline, + &lexer_delim, + &lexer_sep, + &lexer_word, + &lexer_number, + &lexer_less, + &lexer_great, + &lexer_quote, + &lexer_dquote, + &lexer_bquote, + &lexer_backslash, + &lexer_curly_braces, + &lexer_end, +}; + +int ft_is_delim(char c) +{ + return (c == ' ' || c == '\t'); +} + +int lexer_lex(t_list **alst, t_lexer *lexer) +{ + t_token *token; + + if (lexer->str[lexer->pos] == 0 + || (lexer->str[lexer->pos] == '#' + && lexer->state != QUOTE + && lexer->state != DQUOTE)) + return (lexer_end(alst, lexer)); + if (!*alst) + { + if (!(token = token_init()) + || !(*alst = ft_lstnew(token, sizeof(*token)))) + return (-1); + if (token) + free(token); + } + return ((*g_lexer[lexer->state])(alst, lexer)); +} diff --git a/42sh/src/lexer/lexer_newline.c b/42sh/src/lexer/lexer_newline.c new file mode 100644 index 00000000..840acc6a --- /dev/null +++ b/42sh/src/lexer/lexer_newline.c @@ -0,0 +1,25 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* lexer_newline.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ariard +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/23 23:19:46 by ariard #+# #+# */ +/* Updated: 2017/03/20 15:25:03 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int lexer_newline(t_list **alst, t_lexer *lexer) +{ + t_token *token; + + token = (*alst)->content; + if (token->type) + return (lexer_lex(&(*alst)->next, lexer)); + lexer->pos++; + token->type = TK_NEWLINE; + return (lexer_lex(&(*alst)->next, lexer)); +} diff --git a/42sh/src/lexer/lexer_number.c b/42sh/src/lexer/lexer_number.c new file mode 100644 index 00000000..37c669f0 --- /dev/null +++ b/42sh/src/lexer/lexer_number.c @@ -0,0 +1,42 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* lexer_number.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/03 12:06:45 by jhalford #+# #+# */ +/* Updated: 2017/03/16 18:54:46 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int lexer_number(t_list **alst, t_lexer *lexer) +{ + t_token *token; + t_lexstate state; + + token = (*alst)->content; + token->type = TK_IO_NUMBER; + if ((state = get_state_global(lexer)) + || (state = get_state_redir(lexer))) + { + lexer->state = state; + return (lexer_lex(alst, lexer)); + } + else if (ft_isdigit(lexer->str[lexer->pos]) + && (ft_isdigit(lexer->str[lexer->pos + 1]) + || (lexer->str[lexer->pos + 1] == '>' + || lexer->str[lexer->pos + 1] == '<'))) + { + token_append(token, lexer, 0, 0); + lexer->pos++; + return (lexer_number(alst, lexer)); + } + token->type = TK_WORD; + lexer->state = DEFAULT; + token_append(token, lexer, 0, 0); + lexer->pos++; + 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..88d6c349 --- /dev/null +++ b/42sh/src/lexer/lexer_paren.c @@ -0,0 +1,36 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* lexer_paren.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/03 17:37:15 by jhalford #+# #+# */ +/* Updated: 2017/03/22 18:13:07 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int lexer_paren(t_list **alst, t_lexer *lexer) +{ + t_token *token; + + token = (*alst)->content; + if (token->type) + return (lexer_lex(&(*alst)->next, lexer)); + if (lexer->str[lexer->pos] == '(') + { + token->type = TK_PAREN_OPEN; + push(&lexer->stack, PAREN); + } + else + { + token->type = TK_PAREN_CLOSE; + if (get_lexer_stack(*lexer) == PAREN) + pop(&lexer->stack); + } + lexer->pos++; + lexer->state = DEFAULT; + return (lexer_lex(&(*alst)->next, lexer)); +} diff --git a/42sh/src/lexer/lexer_quote.c b/42sh/src/lexer/lexer_quote.c new file mode 100644 index 00000000..f758416f --- /dev/null +++ b/42sh/src/lexer/lexer_quote.c @@ -0,0 +1,36 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* lexer_quote.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/03 12:07:08 by jhalford #+# #+# */ +/* Updated: 2017/03/17 20:16:30 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int lexer_quote(t_list **alst, t_lexer *lexer) +{ + t_token *token; + + token = (*alst)->content; + token->type = token->type ? 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 new file mode 100644 index 00000000..df839bc8 --- /dev/null +++ b/42sh/src/lexer/lexer_sep.c @@ -0,0 +1,41 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* lexer_sep.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/30 16:29:57 by jhalford #+# #+# */ +/* Updated: 2017/03/27 19:53:05 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int lexer_sep(t_list **alst, t_lexer *lexer) +{ + t_token *token; + char c; + char cn; + + lexer->state = DEFAULT; + token = (*alst)->content; + if (token->type) + return (lexer_lex(&(*alst)->next, lexer)); + c = lexer->str[lexer->pos]; + token_append(token, lexer, 0, 0); + lexer->pos++; + cn = lexer->str[lexer->pos]; + if (c == '&') + token->type = cn == '&' ? TK_AND_IF : TK_AMP; + else if (c == '|') + token->type = cn == '|' ? TK_OR_IF : TK_PIPE; + else if (c == ';') + token->type = cn == ';' ? TK_DSEMI : TK_SEMI; + else if (c == '!') + token->type = TK_BANG; + if (token->type == TK_AND_IF || token->type == TK_OR_IF + || token->type == TK_DSEMI) + lexer->pos++; + return (lexer_lex(&(*alst)->next, lexer)); +} diff --git a/42sh/src/lexer/lexer_word.c b/42sh/src/lexer/lexer_word.c new file mode 100644 index 00000000..7a982a71 --- /dev/null +++ b/42sh/src/lexer/lexer_word.c @@ -0,0 +1,39 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* lexer_word.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/03 12:07:11 by jhalford #+# #+# */ +/* Updated: 2017/03/27 19:35:55 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int lexer_word(t_list **alst, t_lexer *lexer) +{ + t_token *token; + t_lexstate state; + + token = (*alst)->content; + token->type = token->type ? token->type : TK_WORD; + if (lexer->str[lexer->pos] != '!' + && ((state = get_state_global(lexer)) + || (state = get_state_redir(lexer)))) + lexer->state = state; + else if (lexer->str[lexer->pos] == '=' + && word_is_assignment((char *[]){token->data, (char *)token->esc})) + { + token->type = TK_ASSIGNMENT_WORD; + token_append(token, lexer, 1, 0); + lexer->pos++; + } + else + { + token_append(token, lexer, 0, 0); + lexer->pos++; + } + return (lexer_lex(alst, lexer)); +} diff --git a/42sh/src/lexer/token_append.c b/42sh/src/lexer/token_append.c new file mode 100644 index 00000000..72a5617b --- /dev/null +++ b/42sh/src/lexer/token_append.c @@ -0,0 +1,53 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* token_append.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/11 17:18:42 by jhalford #+# #+# */ +/* Updated: 2017/03/08 17:45:08 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int token_append_char(t_token *token, char c, + short int esc, short int esc2) +{ + int len; + + len = ft_strlen(token->data); + if (len >= token->size) + { + token->size += 8; + token->data = (char *)ft_realloc(token->data, token->size + 1); + 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[]){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_cmp_type.c b/42sh/src/lexer/token_cmp_type.c new file mode 100644 index 00000000..4185bc7b --- /dev/null +++ b/42sh/src/lexer/token_cmp_type.c @@ -0,0 +1,18 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* token_cmp_type.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/30 17:08:55 by jhalford #+# #+# */ +/* Updated: 2017/01/24 16:02:48 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int token_cmp_type(t_token *token, t_type *ref) +{ + return (!(token->type & *ref)); +} diff --git a/42sh/src/lexer/token_free.c b/42sh/src/lexer/token_free.c new file mode 100644 index 00000000..148ff2b6 --- /dev/null +++ b/42sh/src/lexer/token_free.c @@ -0,0 +1,25 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* token_free.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/03 12:07:30 by jhalford #+# #+# */ +/* Updated: 2017/03/08 13:22:19 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void token_free(void *data, size_t size) +{ + t_token *token; + + (void)size; + token = data; + 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 new file mode 100644 index 00000000..2e90638c --- /dev/null +++ b/42sh/src/lexer/token_init.c @@ -0,0 +1,27 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* token_init.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/10 15:30:25 by jhalford #+# #+# */ +/* Updated: 2017/03/21 18:11:43 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +t_token *token_init(void) +{ + t_token *token; + + if (!(token = (t_token *)ft_malloc(sizeof(t_token)))) + return (NULL); + token->type = 0; + token->size = 8; + token->data = ft_strnew(token->size + 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/line_editing/control_features.c b/42sh/src/line_editing/control_features.c new file mode 100644 index 00000000..4b0d0743 --- /dev/null +++ b/42sh/src/line_editing/control_features.c @@ -0,0 +1,61 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* control_features.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/02 15:17:28 by gwojda #+# #+# */ +/* Updated: 2017/03/24 14:05:58 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int ft_buff_f6(char **str, size_t *pos) +{ + int ret; + + ret = 0; + (void)str; + (void)pos; + if (read(0, &ret, sizeof(int)) < 0) + return (-1); + return (0); +} + +int ft_control_d(char **str, size_t *pos) +{ + if (!data_singleton()->line.is_prompt) + return (0); + if (!*str || (*str)[0] == '\0') + { + ft_putstr("exit\n"); + builtin_exit(NULL, (char*[]){"exit", NULL}, NULL); + data_singleton()->line.is_prompt ? ft_prompt() : ft_putstr("> "); + } + else if (*pos < ft_strlen(*str)) + ft_del(str, pos); + else + ft_puttermcaps("bl"); + return (0); +} + +int ft_control_c(char **str, size_t *pos) +{ + set_exitstatus(1, 1); + if (*str) + ft_current_str(*str, *pos); + ft_strdel(str); + *pos = 0; + return (42); +} + +int ft_control_l(char **str, size_t *pos) +{ + ft_clear_window(); + ft_prompt(); + ft_strdel(str); + *pos = 0; + return (0); +} diff --git a/42sh/src/line_editing/copy_cut_paste/copy_cut_paste.c b/42sh/src/line_editing/copy_cut_paste/copy_cut_paste.c new file mode 100644 index 00000000..6fb8f6c2 --- /dev/null +++ b/42sh/src/line_editing/copy_cut_paste/copy_cut_paste.c @@ -0,0 +1,110 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* copy_cut_paste.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/19 12:45:06 by gwojda #+# #+# */ +/* Updated: 2017/03/27 16:59:59 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +t_cpy g_cpy[] = +{ + {FLECHE_GAUCHE , &underline_left }, + {FLECHE_DROITE , &underline_right }, + {FLECHE_HAUT , &underline_up }, + {FLECHE_BAS , &underline_down }, + {TOUCHE_HOME , &underline_home }, + {TOUCHE_END , &underline_end }, + {0 , 0 }, +}; + +int ft_x(char **str, size_t *pos) +{ + size_t pos_ref; + int ret; + int i; + + pos_ref = *pos; + ft_strdel(&data_singleton()->line.copy_tmp); + data_singleton()->line.pos_tmp = 0; + if (!*str) + return (0); + while (42) + { + ret = 0; + i = 0; + if (read(STDIN, &ret, sizeof(int)) < 0) + return (-1); + while (g_cpy[i].value && g_cpy[i].value != ret) + ++i; + if (g_cpy[i].value && (ret = g_cpy[i].f(str, pos, pos_ref))) + return (0); + else if (!g_cpy[i].value) + break ; + } + if (data_singleton()->line.copy_tmp && *data_singleton()->line.copy_tmp) + reset_and_remove_term(str, pos, data_singleton()->line.copy_tmp); + return (0); +} + +int ft_c(char **str, size_t *pos) +{ + size_t pos_ref; + int ret; + int i; + + pos_ref = *pos; + ft_strdel(&data_singleton()->line.copy_tmp); + data_singleton()->line.pos_tmp = 0; + if (!*str) + return (0); + while (42) + { + ret = 0; + i = 0; + if (read(STDIN, &ret, sizeof(int)) < 0) + return (-1); + while (g_cpy[i].value && g_cpy[i].value != ret) + ++i; + if (g_cpy[i].value && (ret = g_cpy[i].f(str, pos, pos_ref))) + return (0); + else if (!g_cpy[i].value) + break ; + } + reset_term(str, pos); + return (0); +} + +int ft_v(char **str, size_t *pos) +{ + size_t tmp_pos; + int i; + char *tmp; + + i = -1; + tmp_pos = *pos; + tmp = data_singleton()->line.copy_tmp; + if (!*str || !tmp) + return (0); + while (tmp[++i]) + { + if (ft_strlen(*str) > SIZE_LINE) + break ; + *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 + (((*str)[*pos]) ? 1 : 0)); + *pos = tmp_pos; + return (0); +} diff --git a/42sh/src/line_editing/copy_cut_paste/underline_down.c b/42sh/src/line_editing/copy_cut_paste/underline_down.c new file mode 100644 index 00000000..68011b25 --- /dev/null +++ b/42sh/src/line_editing/copy_cut_paste/underline_down.c @@ -0,0 +1,40 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* underline_down.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/23 11:43:40 by gwojda #+# #+# */ +/* Updated: 2017/03/23 16:21:46 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int underline_down(char **str, size_t *pos, size_t pos_ref) +{ + size_t pos_tmp; + int i; + + i = 0; + pos_tmp = *pos; + if ((*str)[pos_tmp] == '\n') + { + underline_right(str, pos, pos_ref); + ++pos_tmp; + } + i = ft_size_term(); + while (i && (*str)[pos_tmp] && (*str)[pos_tmp] != '\n') + { + underline_right(str, pos, pos_ref); + ++pos_tmp; + --i; + } + if ((*str)[pos_tmp] == '\n') + { + underline_left(str, pos, pos_ref); + --pos_tmp; + } + return (0); +} diff --git a/42sh/src/line_editing/copy_cut_paste/underline_end.c b/42sh/src/line_editing/copy_cut_paste/underline_end.c new file mode 100644 index 00000000..6c08cd23 --- /dev/null +++ b/42sh/src/line_editing/copy_cut_paste/underline_end.c @@ -0,0 +1,36 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* underline_end.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/22 23:18:15 by gwojda #+# #+# */ +/* Updated: 2017/03/23 16:21:53 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int underline_end(char **str, size_t *pos, size_t pos_ref) +{ + size_t pos_tmp; + + pos_tmp = *pos; + if ((*str)[pos_tmp] == '\n') + { + underline_right(str, pos, pos_ref); + ++pos_tmp; + } + while ((*str)[pos_tmp] && (*str)[pos_tmp] != '\n') + { + underline_right(str, pos, pos_ref); + ++pos_tmp; + } + if ((*str)[pos_tmp] == '\n') + { + underline_left(str, pos, pos_ref); + --pos_tmp; + } + return (0); +} diff --git a/42sh/src/line_editing/copy_cut_paste/underline_function.c b/42sh/src/line_editing/copy_cut_paste/underline_function.c new file mode 100644 index 00000000..34c0f318 --- /dev/null +++ b/42sh/src/line_editing/copy_cut_paste/underline_function.c @@ -0,0 +1,24 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* underline_function.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/22 20:55:24 by gwojda #+# #+# */ +/* Updated: 2017/03/22 22:59:02 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void underline_check_end_of_line(char *str, size_t pos) +{ + if (!str) + return ; + if (ft_nb_last_line(str, pos) == 0) + { + ft_putchar(str[pos]); + ft_puttermcaps("le"); + } +} diff --git a/42sh/src/line_editing/copy_cut_paste/underline_home.c b/42sh/src/line_editing/copy_cut_paste/underline_home.c new file mode 100644 index 00000000..e1153a65 --- /dev/null +++ b/42sh/src/line_editing/copy_cut_paste/underline_home.c @@ -0,0 +1,33 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* underline_home.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/22 23:11:05 by gwojda #+# #+# */ +/* Updated: 2017/03/23 16:22:01 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int underline_home(char **str, size_t *pos, size_t pos_ref) +{ + size_t pos_tmp; + + pos_tmp = *pos; + if ((*str)[pos_tmp] == '\n') + { + underline_left(str, pos, pos_ref); + --pos_tmp; + } + while ((pos_tmp && (*str)[pos_tmp] != '\n') + && (pos_tmp + 1 > 0 && (*str)[pos_tmp - 1] != '\n')) + { + underline_left(str, pos, pos_ref); + --pos_tmp; + } + *pos = pos_tmp; + return (0); +} diff --git a/42sh/src/line_editing/copy_cut_paste/underline_left.c b/42sh/src/line_editing/copy_cut_paste/underline_left.c new file mode 100644 index 00000000..7bd01924 --- /dev/null +++ b/42sh/src/line_editing/copy_cut_paste/underline_left.c @@ -0,0 +1,64 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* underline_left.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/22 22:54:28 by gwojda #+# #+# */ +/* Updated: 2017/03/23 16:25:19 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static int reset_term_hard(void) +{ + ft_putstr(data_singleton()->line.copy_tmp); + ft_putnc('\b', ft_strlen(data_singleton()->line.copy_tmp)); + ft_strdel(&data_singleton()->line.copy_tmp); + data_singleton()->line.pos_tmp = 0; + return (1); +} + +static void left_abs(char **str, size_t *pos) +{ + --(*pos); + ft_putchar('\b'); + data_singleton()->line.pos_tmp = 0; + ft_puttermcaps("mr"); + ft_putstr("\x1b[38;5;196m"); + data_singleton()->line.copy_tmp = ft_realloc_imput(data_singleton()-> + line.copy_tmp, (*str)[*pos], data_singleton()->line.pos_tmp); + ft_putchar((*str)[*pos]); + underline_check_end_of_line(*str, *pos + 1); + ft_putstr("\033[22;37m"); + ft_puttermcaps("me"); + ft_putchar('\b'); +} + +static void left_mv_back(char **str, size_t *pos) +{ + --(*pos); + ft_putchar('\b'); + ft_putchar((*str)[*pos]); + underline_check_end_of_line(*str, *pos + 1); + data_singleton()->line.copy_tmp = ft_remove_imput(data_singleton()-> + line.copy_tmp, data_singleton()->line.pos_tmp); + if (data_singleton()->line.pos_tmp) + --(data_singleton()->line.pos_tmp); + ft_putchar('\b'); +} + +int underline_left(char **str, size_t *pos, size_t pos_ref) +{ + if (!*pos) + return (0); + if ((*str)[*pos - 1] == '\n') + return (reset_term_hard()); + if (*pos > pos_ref) + left_mv_back(str, pos); + else + left_abs(str, pos); + return (0); +} diff --git a/42sh/src/line_editing/copy_cut_paste/underline_reset.c b/42sh/src/line_editing/copy_cut_paste/underline_reset.c new file mode 100644 index 00000000..e93e34dc --- /dev/null +++ b/42sh/src/line_editing/copy_cut_paste/underline_reset.c @@ -0,0 +1,55 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* underline_reset.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/22 21:14:07 by gwojda #+# #+# */ +/* Updated: 2017/03/23 11:06:25 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void reset_term(char **str, size_t *pos) +{ + size_t pos_ref; + + pos_ref = *pos; + if (*pos) + { + --(*pos); + ft_get_beggin_with_curs(*str, pos); + } + ft_puttermcaps("cd"); + ft_current_str(*str, *pos); + ft_get_next_str(*str, pos); + ft_putnc('\b', *pos - pos_ref + (((*str)[*pos]) ? 1 : 0)); + (*pos) = pos_ref; +} + +void reset_and_remove_term(char **str, size_t *pos, char *copy_tmp) +{ + size_t pos_ref; + + pos_ref = *pos; + if (!data_singleton()->line.pos_tmp) + pos_ref += ft_strlen(data_singleton()->line.copy_tmp); + if (*pos) + { + --(*pos); + ft_get_beggin_with_curs(*str, pos); + } + while (*copy_tmp) + { + --pos_ref; + *str = ft_remove_imput(*str, pos_ref); + ++copy_tmp; + } + ft_puttermcaps("cd"); + ft_current_str(*str, *pos); + ft_get_next_str(*str, pos); + ft_putnc('\b', *pos - pos_ref + (((*str)[*pos]) ? 1 : 0)); + (*pos) = pos_ref; +} diff --git a/42sh/src/line_editing/copy_cut_paste/underline_right.c b/42sh/src/line_editing/copy_cut_paste/underline_right.c new file mode 100644 index 00000000..ebb42684 --- /dev/null +++ b/42sh/src/line_editing/copy_cut_paste/underline_right.c @@ -0,0 +1,60 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* underline_right.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/22 22:50:52 by gwojda #+# #+# */ +/* Updated: 2017/03/23 16:25:34 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static int reset_term_hard(void) +{ + ft_putnc('\b', ft_strlen(data_singleton()->line.copy_tmp)); + ft_putstr(data_singleton()->line.copy_tmp); + ft_strdel(&data_singleton()->line.copy_tmp); + data_singleton()->line.pos_tmp = 0; + return (1); +} + +static void right_abs(char **str, size_t *pos) +{ + ft_puttermcaps("mr"); + ft_putstr("\x1b[38;5;196m"); + data_singleton()->line.copy_tmp = ft_realloc_imput(data_singleton()-> + line.copy_tmp, (*str)[*pos], data_singleton()->line.pos_tmp); + ft_putchar((*str)[*pos]); + ft_putstr("\033[22;37m"); + ft_puttermcaps("me"); + ++(data_singleton()->line.pos_tmp); + ++(*pos); + underline_check_end_of_line(*str, *pos); +} + +static void right_mv_back(char **str, size_t *pos) +{ + data_singleton()->line.copy_tmp = ft_remove_imput(data_singleton()-> + line.copy_tmp, data_singleton()->line.pos_tmp); + ft_putchar((*str)[*pos]); + if (data_singleton()->line.pos_tmp) + --(data_singleton()->line.pos_tmp); + ++(*pos); + underline_check_end_of_line(*str, *pos); +} + +int underline_right(char **str, size_t *pos, size_t pos_ref) +{ + if (!(*pos < ft_strlen(*str))) + return (0); + if ((*str)[*pos] == '\n') + return (reset_term_hard()); + if (*pos >= pos_ref) + right_abs(str, pos); + else + right_mv_back(str, pos); + return (0); +} diff --git a/42sh/src/line_editing/copy_cut_paste/underline_up.c b/42sh/src/line_editing/copy_cut_paste/underline_up.c new file mode 100644 index 00000000..52dc394b --- /dev/null +++ b/42sh/src/line_editing/copy_cut_paste/underline_up.c @@ -0,0 +1,37 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* underline_up.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/23 11:35:48 by gwojda #+# #+# */ +/* Updated: 2017/03/23 16:22:12 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int underline_up(char **str, size_t *pos, size_t pos_ref) +{ + size_t pos_tmp; + int i; + + i = 0; + pos_tmp = *pos; + if ((*str)[pos_tmp] == '\n') + { + underline_left(str, pos, pos_ref); + --pos_tmp; + } + i = ft_size_term(); + while (i && (pos_tmp && (*str)[pos_tmp] != '\n') + && (pos_tmp + 1 > 0 && (*str)[pos_tmp - 1] != '\n')) + { + underline_left(str, pos, pos_ref); + --pos_tmp; + --i; + } + *pos = pos_tmp; + return (0); +} diff --git a/42sh/src/line_editing/ft_prompt.c b/42sh/src/line_editing/ft_prompt.c new file mode 100644 index 00000000..61a355a9 --- /dev/null +++ b/42sh/src/line_editing/ft_prompt.c @@ -0,0 +1,110 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_prompt.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/13 13:51:33 by gwojda #+# #+# */ +/* Updated: 2017/03/27 01:00:56 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static int promt_git_status(int fd) +{ + int len; + char *tmp; + char *line; + + get_next_line(fd, &line); + tmp = line; + if (ft_strrchr(line, '/')) + line = ft_strdup(ft_strrchr(line, '/') + 1); + else + line = ft_strdup(line + 3); + ft_strdel(&tmp); + ft_printf("\x1b[38;5;47mgit:(\x1b[38;5;203m%s\x1b[38;5;47m)", line); + len = ft_strlen(line); + ft_strdel(&line); + if (!get_next_line(fd, &tmp)) + ft_printf("\x1b[38;5;83m ✓ "); + else + ft_printf("\x1b[38;5;1m ✗ "); + ft_strdel(&tmp); + while (get_next_line(fd, &tmp) > 0) + ft_strdel(&tmp); + close(fd); + ft_strdel(&tmp); + return (len + 8); +} + +static int ft_git_status(void) +{ + static char *exec[] = {"git", "status", "--porcelain", "--branch", NULL}; + int pip[2]; + pid_t soon; + int ret; + + pipe(pip); + if ((soon = fork())) + { + waitpid(soon, &ret, WUNTRACED); + if (WEXITSTATUS(ret)) + return (-1); + close(pip[1]); + return (promt_git_status(pip[0])); + } + else + { + dup2(pip[1], 1); + dup2(pip[1], 2); + close(pip[0]); + execve("/usr/bin/git", exec, data_singleton()->env); + } + return (0); +} + +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(void) +{ + int ret; + + ret = 0; + do_job_notification(); + if (ft_getenv(data_singleton()->env, "?") && + ft_atoi(ft_getenv(data_singleton()->env, "?"))) + ft_printf("\x1b[38;5;1m➜ "); + else + ft_printf("\x1b[38;5;10m➜ "); + 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..3647c734 --- /dev/null +++ b/42sh/src/line_editing/get_key.c @@ -0,0 +1,97 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* get_key.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/19 16:28:49 by gwojda #+# #+# */ +/* Updated: 2017/03/21 10:34:46 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_L , &ft_control_l }, + {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 init_read_stdin(char ***str, size_t **pos) +{ + *pos = &data_singleton()->line.pos; + *str = &data_singleton()->line.input; + if (**str) + { + ft_current_str(**str, **pos); + ft_get_next_str(**str, *pos); + if ((**str)[**pos]) + ++(**pos); + } + if (data_singleton()->comp) + c_clear(data_singleton()); + signal(SIGWINCH, sigwinch_resize); +} + +static int read_stdin(int *ret, int *j) +{ + *j = 0; + *ret = 0; + if (read(STDIN, ret, sizeof(int)) < 0) + return (-1); + return (1); +} + +static int press_enter(char **input, char **str) +{ + *input = *str; + return (0); +} + +int ft_read_stdin(char **input) +{ + int ret; + int j; + char **str; + size_t *pos; + + init_read_stdin(&str, &pos); + while (42) + { + if (read_stdin(&ret, &j) < 0) + return (-1); + if (ft_completion(ret, str, pos)) + continue ; + while (g_key[j].value && g_key[j].value != ret) + ++j; + if (g_key[j].value && (ret = g_key[j].f(str, pos))) + return (ret); + else if (!g_key[j].value && ft_isprint(ret)) + ft_print(ret, str, pos); + else if (!g_key[j].value && ret == 10) + return (press_enter(input, str)); + else if (!g_key[j].value && ft_isascii(ret) == 0) + ft_read_it(ret, pos, str); + } +} diff --git a/42sh/src/line_editing/init_line/init_history.c b/42sh/src/line_editing/init_line/init_history.c new file mode 100644 index 00000000..38dc438b --- /dev/null +++ b/42sh/src/line_editing/init_line/init_history.c @@ -0,0 +1,62 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* init_history.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/07 17:34:23 by gwojda #+# #+# */ +/* Updated: 2017/03/21 10:39:24 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static int ft_str_is_print(char *str) +{ + int i; + + i = 0; + while (str[i]) + { + if (!ft_isprint(str[i])) + return (0); + ++i; + } + return (1); +} + +static void corrupt_history(int corrupt, char *home) +{ + if (corrupt) + ft_dprintf(2, "42sh: corrupt history file %s/.42sh_history\n", home); +} + +void ft_init_history(void) +{ + int fd; + char *str; + char *home; + char *path; + char corrupt; + + corrupt = 0; + if (!(home = ft_getenv(data_singleton()->env, "HOME"))) + return ; + path = ft_str3join(home, "/", ".42sh_history"); + if ((fd = open(path, O_RDONLY)) < 0) + return (free(path)); + while (get_next_line(fd, &str) > 0) + { + if (ft_str_is_print(str) && *str) + ft_push_back_history(&data_singleton()->line.list_beg, + ft_create_history_list(str)); + else + corrupt = CORRUPT; + free(str); + } + corrupt_history(corrupt, home); + free(path); + free(str); + close(fd); +} diff --git a/42sh/src/line_editing/init_line/init_line.c b/42sh/src/line_editing/init_line/init_line.c new file mode 100644 index 00000000..9c591e13 --- /dev/null +++ b/42sh/src/line_editing/init_line/init_line.c @@ -0,0 +1,46 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* init_line.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/07 17:34:44 by gwojda #+# #+# */ +/* Updated: 2017/03/22 18:02:25 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_tmp = 0; + 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 readline_init(int has_prompt) +{ + static int beg = 0; + + if (!beg) + { + ft_init_line(); + ft_init_history(); + ft_save_termios(1); + beg = 1; + } + ft_init_termios(); + if (data_singleton()->line.input) + ft_strdel(&data_singleton()->line.input); + data_singleton()->line.list_cur = data_singleton()->line.list_beg; + data_singleton()->line.pos = 0; + has_prompt ? ft_prompt() : ft_putstr("> "); + data_singleton()->line.is_prompt = has_prompt ? 1 : 0; +} diff --git a/42sh/src/line_editing/init_line/init_termcaps.c b/42sh/src/line_editing/init_line/init_termcaps.c new file mode 100644 index 00000000..475bf580 --- /dev/null +++ b/42sh/src/line_editing/init_line/init_termcaps.c @@ -0,0 +1,41 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* init_termcaps.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/07 17:33:41 by gwojda #+# #+# */ +/* Updated: 2017/03/27 17:37:40 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +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 *)ft_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); +} diff --git a/42sh/src/line_editing/lib_line_editing/ft_nb_line.c b/42sh/src/line_editing/lib_line_editing/ft_nb_line.c new file mode 100644 index 00000000..c8fef299 --- /dev/null +++ b/42sh/src/line_editing/lib_line_editing/ft_nb_line.c @@ -0,0 +1,25 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_nb_line.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/08 17:11:57 by gwojda #+# #+# */ +/* Updated: 2017/03/08 17:43:14 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int ft_nb_of_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 / ft_size_term()); +} 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..f3b07f70 --- /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/03/04 18:51:45 by ariard ### ########.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..2703ce09 --- /dev/null +++ b/42sh/src/line_editing/lib_line_editing/tool_line_2.c @@ -0,0 +1,85 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* tool_line_2.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/20 19:07:52 by gwojda #+# #+# */ +/* Updated: 2017/03/17 12:17:07 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void ft_clear_window(void) +{ + ft_puttermcaps("cl"); +} + +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(data_singleton()->line.input); + ft_read_tmp(); + ft_puttermcaps("rc"); + ft_puttermcaps("cd"); + ft_putstr("\033[37m"); +} + +int ft_printall(char **str, size_t *pos) +{ + size_t pos_tmp; + int ret; + + ret = 0; + if (read(0, &ret, sizeof(int)) == -1 || ret != 126 || !*str) + return (0); + 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; + return (0); +} + +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..c07123db --- /dev/null +++ b/42sh/src/line_editing/lib_line_editing/toolz.c @@ -0,0 +1,57 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* toolz.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/16 17:06:30 by gwojda #+# #+# */ +/* Updated: 2017/03/21 18:10:51 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; + if (!(str = (char *)ft_malloc(sizeof(char) * (n + 1)))) + return (NULL); + if (str) + { + while (i < n) + { + str[i] = s[i]; + i++; + } + str[i] = '\0'; + } + 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..fbbc471e --- /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/03/24 11:52:10 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 *)ft_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..478db2dd --- /dev/null +++ b/42sh/src/line_editing/lib_line_editing/toolz_parseur.c @@ -0,0 +1,56 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* toolz_parseur.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/16 16:14:46 by gwojda #+# #+# */ +/* Updated: 2017/03/27 22:06:09 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +char *ft_realloc_imput(char *str, int a, size_t pos) +{ + char tmp[2]; + char *str_tmp; + char *new_str; + + tmp[0] = (char)a; + tmp[1] = '\0'; + if (ft_strlen(str) > SIZE_LINE) + return (str); + if (!str) + { + new_str = ft_strdup(tmp); + return (new_str); + } + if (!(str_tmp = ft_strndup(str, pos))) + return (NULL); + if (!(new_str = ft_strjoin(str_tmp, tmp))) + return (NULL); + free(str_tmp); + if (!(str_tmp = ft_strjoin(new_str, str + pos))) + return (NULL); + 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); + if (!(new_str = ft_strndup(str, pos))) + return (NULL); + if (!(new_str2 = ft_strjoin(new_str, &str[pos + 1]))) + return (NULL); + 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..f93f2917 --- /dev/null +++ b/42sh/src/line_editing/lib_line_editing/toolz_termcaps.c @@ -0,0 +1,64 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* toolz_termcaps.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/08 12:35:11 by gwojda #+# #+# */ +/* Updated: 2017/03/10 17:43:59 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; + } + if (str[pos] == '\n') + --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 % ft_size_term()); +} + +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_term/home_end.c b/42sh/src/line_editing/move_term/home_end.c new file mode 100644 index 00000000..3f3fbe99 --- /dev/null +++ b/42sh/src/line_editing/move_term/home_end.c @@ -0,0 +1,53 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* home_end.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/14 11:13:24 by gwojda #+# #+# */ +/* Updated: 2017/03/17 11:54:33 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int ft_end(char **str, size_t *pos) +{ + if (!*str) + return (0); + 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); + return (0); +} + +int ft_home(char **str, size_t *pos) +{ + if (!*str) + return (0); + 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); + return (0); +} diff --git a/42sh/src/line_editing/move_term/move_left_and_right.c b/42sh/src/line_editing/move_term/move_left_and_right.c new file mode 100644 index 00000000..ab7c9ca8 --- /dev/null +++ b/42sh/src/line_editing/move_term/move_left_and_right.c @@ -0,0 +1,82 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* move_left_and_right.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/19 16:43:58 by gwojda #+# #+# */ +/* Updated: 2017/03/29 17:45:36 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static void check_end_right(char *str, size_t pos) +{ + if (!str) + return ; + if (ft_nb_last_line(str, pos) == 0) + { + ft_putchar(str[pos]); + ft_puttermcaps("le"); + } +} + +int ft_move_right(char **str, size_t *pos) +{ + size_t tmp; + + if (ft_strlen(*str) <= *pos) + return (0); + 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); + check_end_right(*str, *pos); + } + return (0); +} + +int ft_move_left(char **str, size_t *pos) +{ + if (!*pos) + return (0); + if ((*str)[*pos - 1] == '\n') + { + if (*pos - 1 == 0) + { + ft_puttermcaps("cd"); + --(*pos); + return (0); + } + 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); + } + return (0); +} diff --git a/42sh/src/line_editing/move_term/move_to_word.c b/42sh/src/line_editing/move_term/move_to_word.c new file mode 100644 index 00000000..cd0d90ab --- /dev/null +++ b/42sh/src/line_editing/move_term/move_to_word.c @@ -0,0 +1,130 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* move_to_word.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/14 11:12:09 by gwojda #+# #+# */ +/* Updated: 2017/03/24 12:12:11 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; + (*pos) -= ((ft_nb_last_line(str, *pos) == 0) ? 1 : 0); +} + +int ft_found_prev_word(char **str, size_t *pos) +{ + int i; + + i = 0; + if (!*pos || !*str) + return (0); + ft_init_prev_word(pos, *str); + if (*pos >= 1 && (*str)[*pos - 1] == '\n') + { + if (*pos - 1 == 0) + { + ft_puttermcaps("cd"); + --(*pos); + return (0); + } + ft_puttermcaps("cd"); + *pos -= 2; + ft_get_beggin(*str, pos); + (!*pos && (*str)[*pos] == '\n') ? ++(*pos) : 0; + ft_current_str(*str, *pos); + ft_get_next_str(*str, pos); + ++(*pos); + } + else + ft_found_prev_word_2(i, *str, pos); + return (0); +} + +static void ft_found_next_word_2(char **str, size_t *pos) +{ + 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); +} + +int ft_found_next_word(char **str, size_t *pos) +{ + int i; + + i = 0; + if (!*str) + return (0); + while ((*str)[i + *pos] && (*str)[i + *pos] == ' ') + { + ft_putchar((*str)[i + *pos]); + ++i; + } + if ((*str)[*pos] == '\n') + ft_found_next_word_2(str, pos); + else + { + while ((*str)[i + *pos] && (*str)[i + *pos] != '\n' && + (*str)[i + *pos] != ' ') + { + ft_putchar((*str)[i + *pos]); + ++i; + } + *pos += i; + } + return (0); +} diff --git a/42sh/src/line_editing/move_term/move_up_and_down.c b/42sh/src/line_editing/move_term/move_up_and_down.c new file mode 100644 index 00000000..f72088a7 --- /dev/null +++ b/42sh/src/line_editing/move_term/move_up_and_down.c @@ -0,0 +1,98 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* move_up_and_down.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/09 13:21:40 by gwojda #+# #+# */ +/* Updated: 2017/03/17 11:44:08 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; +} + +int ft_up(char **str, size_t *pos) +{ + if (!*str || !*pos) + return (0); + 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); + return (0); +} + +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); +} + +int ft_down(char **str, size_t *pos) +{ + int i; + int len; + + i = 0; + if (!*str) + return (0); + 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; + } + return (0); +} diff --git a/42sh/src/line_editing/print_del_completion/completion.c b/42sh/src/line_editing/print_del_completion/completion.c new file mode 100644 index 00000000..8a21df39 --- /dev/null +++ b/42sh/src/line_editing/print_del_completion/completion.c @@ -0,0 +1,57 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* completion.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/03 14:15:55 by gwojda #+# #+# */ +/* Updated: 2017/03/17 17:22:02 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static size_t ft_strleni_w(char *str, size_t pos, char c) +{ + size_t len; + + len = 0; + if (!str) + return (0); + while (str[pos] && str[pos] != c) + { + ++len; + ++pos; + } + return (len); +} + +int ft_completion(int ret, char **str, size_t *pos) +{ + size_t tmp; + size_t pos_tmp; + size_t right; + char boolean; + + boolean = 0; + pos_tmp = *pos; + right = ft_strleni_w(*str, *pos, '\n'); + if (((ret != TOUCHE_TAB && ret != 10) + || (ret == 10)) && !(data_singleton()->comp)) + return (0); + if (data_singleton()->comp || ret == TOUCHE_TAB) + boolean = completion(ret); + if (boolean || ret == 10) + { + (pos_tmp) ? --pos_tmp : ft_puttermcaps("nd"); + ft_get_beggin_with_curs(*str, &pos_tmp); + tmp = pos_tmp; + ft_puttermcaps("cd"); + ft_current_str(*str, tmp); + ft_get_next_str(*str, &tmp); + ft_putnc('\b', right); + *pos = pos_tmp + ft_strleni_w(*str, pos_tmp, '\n') - right; + } + return (1); +} diff --git a/42sh/src/line_editing/print_del_completion/print_and_del.c b/42sh/src/line_editing/print_del_completion/print_and_del.c new file mode 100644 index 00000000..9dd948ca --- /dev/null +++ b/42sh/src/line_editing/print_del_completion/print_and_del.c @@ -0,0 +1,111 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* print_and_del.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/05 16:02:43 by gwojda #+# #+# */ +/* Updated: 2017/03/27 22:07:39 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); +} + +int ft_print(int ret, char **str, size_t *pos) +{ + int j; + + j = 0; + if (ft_strlen(*str) > SIZE_LINE) + return (0); + if (!(*str = ft_realloc_imput(*str, ret, *pos))) + return (-1); + 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); + return (0); +} + +static 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 (!**str) + ft_strdel(str); +} + +int ft_suppr(char **str, size_t *pos) +{ + size_t tmp; + char boolean; + + boolean = 0; + if (*pos <= 0) + return (0); + if ((*str)[*pos - 1] != '\n') + boolean = 1; + --(*pos); + tmp = *pos; + if (boolean) + { + ft_get_beggin_with_curs(*str, pos); + if (!(*str = ft_remove_imput(*str, tmp))) + return (-1); + } + else + { + if (!(*str = ft_remove_imput(*str, tmp))) + return (-1); + ft_get_beggin(*str, pos); + } + ft_suppr_2(str, pos, tmp); + return (0); +} + +int ft_del(char **str, size_t *pos) +{ + size_t tmp; + + tmp = *pos; + if (!(*str && *pos < ft_strlen(*str))) + return (0); + if (!(*str = ft_remove_imput(*str, tmp))) + return (-1); + 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; + if (!**str) + ft_strdel(str); + return (0); +} diff --git a/42sh/src/line_editing/print_del_completion/queue.c b/42sh/src/line_editing/print_del_completion/queue.c new file mode 100644 index 00000000..300b63ef --- /dev/null +++ b/42sh/src/line_editing/print_del_completion/queue.c @@ -0,0 +1,79 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* queue.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/19 16:52:57 by gwojda #+# #+# */ +/* Updated: 2017/03/21 10:15:13 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static int 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])) + { + if (ft_strlen(*str) > SIZE_LINE) + return (0); + if (!(*str = ft_realloc_imput(*str, t[i], *pos))) + return (-1); + ++(*pos); + ++(*j); + } + ++i; + } + return (0); +} + +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'; +} + +int 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 (0); + ft_read_it_2(input, t); + if (ft_read_it_3(str, t, pos, &j) < 0) + return (-1); + if (!*str) + return (0); + *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); + return (0); +} diff --git a/42sh/src/line_editing/readline.c b/42sh/src/line_editing/readline.c new file mode 100644 index 00000000..4e3170a8 --- /dev/null +++ b/42sh/src/line_editing/readline.c @@ -0,0 +1,42 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* readline.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/15 14:19:48 by gwojda #+# #+# */ +/* Updated: 2017/03/28 14:57:13 by wescande ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int readline(int has_prompt, char **input) +{ + int ret; + + if (!has_prompt) + data_singleton()->line.prompt_size = 1; + if (!SH_IS_INTERACTIVE(data_singleton()->opts)) + { + ft_strdel(input); + if ((ret = get_next_line(data_singleton()->fd, input)) >= 0) + return (!ret); + return (ret); + } + readline_init(has_prompt); + ret = ft_read_stdin(input); + if (ret < 0) + return (ret); + if (data_singleton()->line.input) + ft_current_str(data_singleton()->line.input, + data_singleton()->line.pos); + ft_putchar('\n'); + if (has_prompt) + ret = ft_history_parsing(has_prompt, input); + ft_strdel(&data_singleton()->line.copy_tmp); + if (tcsetattr(0, TCSANOW, ft_save_termios(0)) == -1) + return (-1); + return (ret); +} diff --git a/42sh/src/line_editing/resize.c b/42sh/src/line_editing/resize.c new file mode 100644 index 00000000..3a1f07c0 --- /dev/null +++ b/42sh/src/line_editing/resize.c @@ -0,0 +1,30 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* resize.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/14 10:56:08 by gwojda #+# #+# */ +/* Updated: 2017/03/21 18:11:12 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void sigwinch_resize(int sig) +{ + size_t pos_tmp; + + pos_tmp = 0; + (void)sig; + if (data_singleton()->comp) + { + c_term_resize(data_singleton()->comp); + ft_puttermcaps("cl"); + data_singleton()->line.is_prompt ? ft_prompt() : ft_putstr("> "); + ft_putall_current_str(data_singleton()->line.input, &pos_tmp); + ft_putnc('\b', pos_tmp - data_singleton()->line.pos); + c_dispatcher(data_singleton()); + } +} diff --git a/42sh/src/main/data_exit.c b/42sh/src/main/data_exit.c new file mode 100644 index 00000000..781bffd1 --- /dev/null +++ b/42sh/src/main/data_exit.c @@ -0,0 +1,34 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* data_exit.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/07 18:07:50 by jhalford #+# #+# */ +/* Updated: 2017/03/27 19:44:27 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void data_exit(void) +{ + t_data *data; + + data = data_singleton(); + ft_strdel(&data->binary); + ft_sstrfree(data->env); + ft_sstrfree(data->local_var); + ft_sstrfree(data->argv); + lexer_destroy(&data->lexer); + parser_destroy(&data->parser); + exec_destroy(&data->exec); + jobc_destroy(&data->jobc); + shell_fds_destroy(); + ft_lstdel(&data->lst_func, &tree_func_free); + ft_save_termios(-1); + ft_free_hash_table(); + free_history_list(data->line.list_beg); + free(data_singleton()); +} diff --git a/42sh/src/main/data_init.c b/42sh/src/main/data_init.c new file mode 100644 index 00000000..d8f7c41d --- /dev/null +++ b/42sh/src/main/data_init.c @@ -0,0 +1,103 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* data_init.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/28 19:26:32 by jhalford #+# #+# */ +/* Updated: 2017/03/27 18:04:11 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static int path_binary_save(char *binary) +{ + char *directory; + + if (binary[0] != '/') + { + if (!(directory = getcwd(NULL, 0))) + return (1); + while (binary[0] == '.' && binary[1] == '/') + binary += 2; + binary = ft_strjoin( + directory[ft_strlen(directory) - 1] != '/' ? "/" : "", binary); + binary = ft_strjoinf(directory, binary, 3); + } + else + binary = ft_strdup(binary); + if (access(binary, F_OK | X_OK)) + return (1); + data_singleton()->binary = binary; + return (0); +} + +static int localenv_init(void) +{ + t_data *data; + char *pid; + + pid = ft_itoa(getpid()); + data = data_singleton(); + data->local_var = NULL; + builtin_setenv(NULL, (char *[]){"local", "IFS", " \t\n", 0}, NULL); + builtin_setenv(NULL, (char *[]){"local", "PS2", " >", 0}, NULL); + ft_strdel(&pid); + return (0); +} + +static int shlvl_inc(void) +{ + t_data *data; + char *shlvl; + + data = data_singleton(); + if ((shlvl = ft_getenv(data->env, "SHLVL"))) + { + if (!(shlvl = ft_itoa(ft_atoi(shlvl) + 1))) + return (-1); + } + else if (!(shlvl = ft_strdup("1"))) + return (-1); + builtin_setenv(NULL, (char *[]){"setenv", "SHLVL", shlvl, 0}, NULL); + ft_strdel(&shlvl); + return (0); +} + +int modules_init(t_data *data) +{ + lexer_init(&data->lexer); + parser_init(&data->parser); + exec_init(&data->exec); + jobc_init(&data->jobc); + return (0); +} + +int data_init(int ac, char **av, char **env) +{ + t_data *data; + char *term_name; + + data = data_singleton(); + data->argc = ac; + data->argv = ft_sstrdup(av); + data->env = ft_sstrdup(env); + data->c_arg = NULL; + set_exitstatus(0, 1); + localenv_init(); + if (shlvl_inc()) + return (-1); + modules_init(data); + data->comp = NULL; + data->opts = SH_INTERACTIVE | SH_OPTS_JOBC; + data->lst_func = NULL; + if ((term_name = ft_getenv(data->env, "TERM")) == NULL) + term_name = "dumb"; + if (tgetent(NULL, term_name) != 1) + return (SH_ERR("TERM name is not a tty") ? -1 : -1); + if (path_binary_save(av[0])) + return (SH_ERR("Failed to resolve binary name") ? -1 : -1); + return (0); +} diff --git a/42sh/src/main/data_singleton.c b/42sh/src/main/data_singleton.c new file mode 100644 index 00000000..9765b47f --- /dev/null +++ b/42sh/src/main/data_singleton.c @@ -0,0 +1,22 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* data_singleton.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/10 11:36:39 by jhalford #+# #+# */ +/* Updated: 2017/03/21 18:10:49 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +t_data *data_singleton(void) +{ + static t_data *data = NULL; + + if (data == NULL) + data = ft_malloc(sizeof(t_data)); + return (data); +} diff --git a/42sh/src/main/main.c b/42sh/src/main/main.c new file mode 100644 index 00000000..77242074 --- /dev/null +++ b/42sh/src/main/main.c @@ -0,0 +1,100 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* main.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gwojda +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/20 14:45:40 by gwojda #+# #+# */ +/* Updated: 2017/03/29 15:27:46 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static int do_readline_routine(char **stream) +{ + int ret; + int has_prompt; + t_data *data; + + data = data_singleton(); + has_prompt = !(get_lexer_stack(data->lexer) + || data->parser.state == UNDEFINED || data->lexer.state == HEREDOC); + ret = readline(has_prompt, stream); + if (ret == -1) + { + ft_strdel(stream); + exit(1); + } + if (ret == 1 && data->parser.state == UNDEFINED) + error_eof(); + return (ret); +} + +static int exec_instruction(t_btree **ast, char **stream) +{ + t_data *data; + + data = data_singleton(); + if (SH_IS_INTERACTIVE(data->opts) && data->lexer.str) + ft_add_str_in_history(data->lexer.str); + else + ft_strdel(stream); + if (data->parser.state == SUCCESS && ft_exec(ast) < 0) + exit(1); + else if (data->parser.state != SUCCESS) + set_exitstatus(1, 1); + return (0); +} + +static int handle_instruction(t_list **token, t_btree **ast) +{ + int ret; + char *stream; + t_data *data; + + stream = NULL; + data = data_singleton(); + while (1) + { + if ((ret = do_readline_routine(&stream)) > 0) + return (ret); + if (do_lexer_routine(token, stream) > 0) + continue ; + if ((ret = do_parser_routine(token, ast)) == 1 + && SH_NO_INTERACTIVE(data->opts)) + return (ret); + else if (ret > 0) + break ; + } + return (exec_instruction(ast, &stream)); +} + +int main(int ac, char **av, char **env) +{ + int ret; + t_data *data; + t_list *token; + t_btree *ast; + + g_argv = av; + if (shell_init(ac, av, env) != 0) + return (1); + token = NULL; + ast = NULL; + data = data_singleton(); + while (1) + { + ret = handle_instruction(&token, &ast); + lexer_destroy(&data->lexer); + parser_destroy(&data->parser); + exec_destroy(&data->exec); + ft_lstdel(&token, &token_free); + btree_del(&ast, &ast_free); + if (ret == 1) + break ; + } + builtin_exit(NULL, NULL, NULL); + return (0); +} diff --git a/42sh/src/main/shell_fds.c b/42sh/src/main/shell_fds.c new file mode 100644 index 00000000..97487b80 --- /dev/null +++ b/42sh/src/main/shell_fds.c @@ -0,0 +1,84 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* shell_fds.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/27 15:32:13 by jhalford #+# #+# */ +/* Updated: 2017/03/27 18:02:46 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void shell_fds_init(void) +{ + t_data *data; + int i; + + data = data_singleton(); + i = -1; + while (++i < 10) + data->fd_save[i] = NULL; +} + +int shell_fds_push(void) +{ + t_data *data; + int i; + int fd; + + data = data_singleton(); + i = -1; + while (++i < 10) + { + fd = fcntl(i, F_DUPFD_CLOEXEC, 10); + push(&(data->fd_save[i]), fd); + } + return (0); +} + +int shell_fds_pop(void) +{ + t_data *data; + int i; + int fd; + + data = data_singleton(); + i = -1; + while (++i < 10) + { + fd = pop(&data->fd_save[i]); + if (fd != -1) + close(fd); + } + return (0); +} + +void shell_fds_reset(void) +{ + t_data *data; + int i; + int fd; + + data = data_singleton(); + i = -1; + while (++i < 10) + { + fd = top(data->fd_save[i]); + if (fd != -1) + dup2(fd, i); + } +} + +void shell_fds_destroy(void) +{ + t_data *data; + int i; + + data = data_singleton(); + i = -1; + while (++i < 10) + ft_lstdel(&data->fd_save[i], ft_lst_cfree); +} diff --git a/42sh/src/main/shell_init.c b/42sh/src/main/shell_init.c new file mode 100644 index 00000000..7cc06210 --- /dev/null +++ b/42sh/src/main/shell_init.c @@ -0,0 +1,105 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* shell_init.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/12 17:23:59 by jhalford #+# #+# */ +/* Updated: 2017/03/27 19:44:20 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" +#define SHELL_USAGE1 "usage: 42sh [--no-jobcontrol]" +#define SHELL_USAGE2 " or 42sh -c command" +#define SHELL_USAGE3 " or 42sh script" + +static t_cliopts g_opts[] = +{ + {'c', NULL, SH_OPTS_LC, SH_OPTS_JOBC | SH_INTERACTIVE, get_c_arg, 1}, + {-1, "no-jobcontrol", 0, SH_OPTS_JOBC, NULL, 0}, + {0, 0, 0, 0, 0, 0}, +}; + +int get_c_arg(char *opt_arg, t_data *data) +{ + if (!opt_arg) + return (1); + if (data) + data->c_arg = opt_arg; + return (0); +} + +static int get_input_fd(t_data *data, char *file) +{ + static int fds[2] = {-1, STDIN}; + struct stat buf; + + if (data->opts & SH_OPTS_LC && (file = data->c_arg)) + { + pipe(fds); + write(fds[PIPE_WRITE], file, ft_strlen(file)); + close(fds[PIPE_WRITE]); + } + else if ((file = *data->av_data)) + { + if (stat(file, &buf) < 0) + SH_ERR("%s: No such file or directory", file); + else if (S_ISDIR(buf.st_mode)) + SH_ERR("%s: is a directory", file); + else if ((fds[PIPE_READ] = open(file, O_RDONLY | O_CLOEXEC)) < 0) + SH_ERR("%s: No such file or directory", file); + } + else + return (STDIN); + if (fds[PIPE_READ] < 0) + return (-1); + fds[PIPE_WRITE] = fcntl(fds[PIPE_READ], F_DUPFD_CLOEXEC, 10); + close(fds[PIPE_READ]); + return (fds[PIPE_WRITE]); +} + +static int interactive_settings(void) +{ + int *shell_pgid; + t_data *data; + + data = data_singleton(); + shell_pgid = &data->jobc.shell_pgid; + while (tcgetpgrp(STDIN) != (*shell_pgid = getpgrp())) + kill(-*shell_pgid, SIGTTIN); + *shell_pgid = getpid(); + shell_sig_reset(); + if (setpgid(*shell_pgid, *shell_pgid)) + { + SH_ERR("setpgid(): %s", strerror(errno)); + return (-1); + } + tcsetpgrp(STDIN, *shell_pgid); + tcgetattr(STDIN, &data->jobc.shell_tmodes); + return (0); +} + +int shell_init(int ac, char **av, char **env) +{ + t_data *data; + + data = data_singleton(); + if (data_init(ac, av, env) < 0) + return (-1); + if (cliopts_get(av, g_opts, data)) + { + return (ft_perror(NULL) && SH_ERR("%s", SHELL_USAGE1) + && SH_ERR("%s", SHELL_USAGE2) && SH_ERR("%s", SHELL_USAGE3)); + } + if (!isatty(STDIN) || *data->av_data) + data->opts &= ~(SH_INTERACTIVE | SH_OPTS_JOBC); + if ((data->fd = get_input_fd(data, NULL)) < 0) + return (-1); + if (SH_IS_INTERACTIVE(data->opts) && interactive_settings() < 0) + return (-1); + shell_fds_init(); + shell_fds_push(); + return (0); +} diff --git a/42sh/src/main/shell_sig.c b/42sh/src/main/shell_sig.c new file mode 100644 index 00000000..01ced561 --- /dev/null +++ b/42sh/src/main/shell_sig.c @@ -0,0 +1,23 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* shell_sig_reset.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/27 15:35:01 by jhalford #+# #+# */ +/* Updated: 2017/03/27 15:35:01 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void shell_sig_reset(void) +{ + signal(SIGINT, SIG_IGN); + signal(SIGQUIT, SIG_IGN); + signal(SIGTSTP, SIG_IGN); + signal(SIGTTIN, SIG_IGN); + signal(SIGTTOU, SIG_IGN); + signal(SIGCHLD, SIG_DFL); +} diff --git a/42sh/src/parser/add_bang.c b/42sh/src/parser/add_bang.c new file mode 100644 index 00000000..6cc0da66 --- /dev/null +++ b/42sh/src/parser/add_bang.c @@ -0,0 +1,79 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* add_bang.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ariard +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/10 14:57:45 by ariard #+# #+# */ +/* Updated: 2017/03/22 15:34:25 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int isbang(t_btree **ast, t_list **lst) +{ + t_astnode *node; + + (void)lst; + node = NULL; + if (*ast) + { + node = (*ast)->item; + if ((node->type == TK_NEWLINE || node->type == TK_SEMI + || node->type == TK_AMP || node->type == TK_AND_IF + || node->type == TK_OR_IF || node->type == TK_PIPE) + && isbang(&(*ast)->right, lst) == 1) + return (1); + if (node->type == TK_BANG && node->full == 0) + return (1); + } + return (0); +} + +int isbang_sep(t_btree **ast, t_list **lst) +{ + t_astnode *node; + t_token *token; + + token = (*lst)->content; + if (*ast) + { + node = (*ast)->item; + if ((token->type == TK_SEMI || token->type == TK_AMP + || token->type == TK_NEWLINE || token->type == TK_AND_IF + || token->type == TK_OR_IF) && node->type == TK_BANG + && node->nest == 0) + node->full = 1; + if (token->type == TK_PIPE && node->type == TK_BANG + && node->full == 0) + return (1); + } + return (0); +} + +int add_bang(t_btree **ast, t_list **lst) +{ + t_astnode *node; + t_token *token; + + token = (*lst)->content; + node = (*ast)->item; + if ((token->type == TK_CASE || token->type == TK_WHILE + || token->type == TK_IF || token->type == TK_UNTIL + || token->type == TK_FOR || token->type == SUBSHELL + || token->type == TK_LBRACE) && node->type == TK_BANG) + node->nest++; + if ((token->type == TK_DONE || token->type == TK_ESAC + || token->type == TK_FI || token->type == TK_RBRACE + || token->type == TK_PAREN_CLOSE) + && node->type == TK_BANG && node->nest > 0) + node->nest--; + return (add_cmd(&(*ast)->right, lst)); +} + +int add_bang_sep(t_btree **ast, t_list **lst) +{ + return (add_sep(&(*ast)->right, lst)); +} diff --git a/42sh/src/parser/add_case.c b/42sh/src/parser/add_case.c new file mode 100644 index 00000000..889b6142 --- /dev/null +++ b/42sh/src/parser/add_case.c @@ -0,0 +1,75 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* add_case.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ariard +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/04 20:42:13 by ariard #+# #+# */ +/* Updated: 2017/03/24 15:17:40 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int iscase(t_btree **ast, t_list **lst) +{ + t_astnode *node; + + (void)lst; + node = NULL; + if (*ast) + { + node = (*ast)->item; + if ((node->type == TK_NEWLINE || node->type == TK_SEMI + || node->type == TK_AMP || node->type == TK_PIPE + || node->type == TK_AND_IF || node->type == TK_OR_IF) + && iscase(&(*ast)->right, lst) == 1) + return (1); + if ((node->type == TK_CASE || node->type == TK_PAREN_OPEN) + && node->pattern == 1 && node->full == 0) + return (1); + } + return (0); +} + +int iscase_branch(t_btree **ast, t_list **lst) +{ + t_astnode *node; + t_token *token; + + node = NULL; + token = (*lst)->content; + if (*ast) + { + node = (*ast)->item; + if ((node->type == TK_PAREN_OPEN) + && node->nest == 0 && token->type == TK_PAREN_OPEN) + return (1); + } + return (0); +} + +int add_case_cmd(t_btree **ast, t_list **lst) +{ + t_astnode *node; + t_token *token; + + token = (*lst)->content; + node = (*ast)->item; + if (token->type == TK_CASE && (node->type == TK_PAREN_OPEN + || node->type == TK_CASE)) + node->nest++; + if (token->type == TK_ESAC && (node->type == TK_PAREN_OPEN + || node->type == TK_CASE) && node->nest > 0) + node->nest--; + else if (token->type == TK_DSEMI && node->type == TK_PAREN_OPEN + && node->nest == 0) + return ((node->full = 1)); + else if ((token->type == TK_ESAC) && node->nest == 0 + && (node->type == TK_CASE || node->type == TK_PAREN_OPEN)) + return ((node->full = 1)); + else if (token->type == TK_PAREN_CLOSE) + return (0); + return (add_cmd(&(*ast)->right, lst)); +} diff --git a/42sh/src/parser/add_cmd.c b/42sh/src/parser/add_cmd.c new file mode 100644 index 00000000..b1c71b6e --- /dev/null +++ b/42sh/src/parser/add_cmd.c @@ -0,0 +1,109 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* add_cmd.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ariard +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/15 20:49:15 by ariard #+# #+# */ +/* Updated: 2017/03/24 19:25:02 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static t_distrostree g_distrostree[] = +{ + {&superflous_token, &add_null}, + {&isloop, &add_loop_cmd}, + {&iscondition_branch, &add_branch}, + {&iscondition, &add_condition_cmd}, + {&iscase, &add_case_cmd}, + {&iscase_branch, &add_branch}, + {&issubshell, &add_subshell_cmd}, + {&isfunc_name, &add_null}, + {&isfunc, &add_func_cmd}, + {&isionumber, &add_ionumber}, + {&isbang, &add_bang}, + {&isdir_sep, &add_redir_type}, + {&isdir_word, &add_redir_word}, + {&isnull, &add_null}, +}; + +int superflous_token(t_btree **ast, t_list **lst) +{ + t_token *token; + + (void)ast; + if (*lst) + { + token = (*lst)->content; + if (token->type == TK_IN) + return (1); + } + return (0); +} + +static int emblematic_token(t_btree **ast, t_list **lst) +{ + t_astnode *node; + t_token *token; + + node = NULL; + token = (*lst)->content; + if (*ast) + { + node = (*ast)->item; + if (token->type == TK_WORD && (node->type == TK_CASE + || node->type == TK_PAREN_OPEN)) + return (0); + if (node->type != TK_DO && node->type != TK_THEN + && node->type != CMD && node->type != REDIR + && node->type != TK_FOR) + return (1); + } + return (0); +} + +static int add_data_node(t_btree **ast, t_list **lst) +{ + t_token *token; + t_astnode *node; + + token = (*lst)->content; + node = (*ast)->item; + if (token->type == TK_IF) + add_if(ast, lst); + else if (token->type != TK_WORD && token->type != TK_NAME) + node->type = token->type; + else if (node->type != TK_CASE && node->type != TK_PAREN_OPEN + && node->type != TK_FOR) + node->type = CMD; + if (token->type == TK_WORD || token->type == TK_ASSIGNMENT_WORD + || token->type == TK_NAME) + ft_ld_pushback(&node->data.cmd.token, + gen_tab(token->data, token->esc, token->esc2, 1)); + if ((token->type == TK_WORD || token->type == TK_NAME) + && (node->type == TK_CASE || node->type == TK_PAREN_OPEN)) + node->pattern = 1; + if (token->type == SUBSHELL || token->type == TK_LBRACE) + node->nest = 1; + return (0); +} + +int add_cmd(t_btree **ast, t_list **lst) +{ + int i; + + i = -1; + while (++i < 14) + { + if (g_distrostree[i].test(ast, lst) == 1) + return (g_distrostree[i].add(ast, lst)); + } + if (!*ast) + gen_node(ast); + else if (emblematic_token(ast, lst)) + return (add_cmd(&(*ast)->right, lst)); + return (add_data_node(ast, lst)); +} diff --git a/42sh/src/parser/add_condition.c b/42sh/src/parser/add_condition.c new file mode 100644 index 00000000..0a8f04d2 --- /dev/null +++ b/42sh/src/parser/add_condition.c @@ -0,0 +1,98 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* add_condition.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ariard +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/10 17:06:16 by ariard #+# #+# */ +/* Updated: 2017/03/22 15:33:12 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int iscondition(t_btree **ast, t_list **lst) +{ + t_astnode *node; + + node = NULL; + if (*ast) + { + node = (*ast)->item; + if ((node->type == TK_NEWLINE || node->type == TK_SEMI + || node->type == TK_AMP || node->type == TK_PIPE + || node->type == TK_AND_IF || node->type == TK_OR_IF) + && iscondition(&(*ast)->right, lst) == 1) + return (1); + if ((node->type == TK_IF || node->type == TK_ELIF + || node->type == TK_ELSE) && node->full == 0) + return (1); + } + return (0); +} + +int iscondition_branch(t_btree **ast, t_list **lst) +{ + t_astnode *node; + t_token *token; + + node = NULL; + token = (*lst)->content; + if (*ast) + { + node = (*ast)->item; + if ((node->type == TK_ELIF) + && (token->type == TK_ELIF || token->type == TK_ELSE) + && node->nest == 0) + return (1); + } + return (0); +} + +int add_condition_cmd(t_btree **ast, t_list **lst) +{ + t_token *token; + t_astnode *node; + + token = (*lst)->content; + node = (*ast)->item; + if (token->type == TK_IF && (node->type == TK_IF || node->type == TK_ELIF + || node->type == TK_ELSE)) + node->nest++; + if (token->type == TK_FI && (node->type == TK_IF || node->type == TK_ELIF + || node->type == TK_ELSE) && node->nest > 0) + node->nest--; + else if (token->type == TK_FI && (node->type == TK_IF + || node->type == TK_ELIF || node->type == TK_ELSE)) + return ((node->full = 1)); + if (token->type == TK_THEN) + return (add_cmd(&(*ast)->right, lst)); + else if (!(*ast)->right) + return (add_cmd(&(*ast)->left, lst)); + else + return (add_cmd(&(*ast)->right, lst)); + return (0); +} + +int add_condition_sep(t_btree **ast, t_list **lst) +{ + if (!(*ast)->right) + return (add_sep(&(*ast)->left, lst)); + else + return (add_sep(&(*ast)->right, lst)); + return (0); +} + +int add_if(t_btree **ast, t_list **lst) +{ + t_token *token; + t_astnode *node; + + token = (*lst)->content; + node = (*ast)->item; + node->type = TK_IF; + token->type = TK_ELIF; + add_cmd(&(*ast)->right, lst); + return (0); +} diff --git a/42sh/src/parser/add_func.c b/42sh/src/parser/add_func.c new file mode 100644 index 00000000..9a4e85d5 --- /dev/null +++ b/42sh/src/parser/add_func.c @@ -0,0 +1,76 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* add_func.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ariard +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/24 23:43:07 by ariard #+# #+# */ +/* Updated: 2017/03/24 23:23:35 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int isfunc_name(t_btree **ast, t_list **lst) +{ + t_astnode *node; + t_token *token; + + token = (*lst)->content; + if (*ast) + { + node = (*ast)->item; + if (node->type == CMD && token->type == TK_PAREN_OPEN) + { + node->type = FNAME; + return (1); + } + } + return (0); +} + +int isfunc(t_btree **ast, t_list **lst) +{ + t_astnode *node; + + (void)lst; + node = NULL; + if (*ast) + { + node = (*ast)->item; + if ((node->type == TK_NEWLINE || node->type == TK_SEMI + || node->type == TK_AMP || node->type == TK_PIPE) + && isfunc(&(*ast)->right, lst) == 1) + return (1); + if (node->type == FNAME && node->full == 0) + return (1); + } + return (0); +} + +int add_func_cmd(t_btree **ast, t_list **lst) +{ + t_astnode *node; + t_token *token; + + token = (*lst)->content; + node = (*ast)->item; + if ((token->type == TK_CASE || token->type == TK_WHILE + || token->type == TK_IF || token->type == TK_UNTIL + || token->type == TK_FOR || token->type == SUBSHELL + || token->type == TK_LBRACE || token->type == TK_PAREN_OPEN) + && node->type == FNAME) + node->nest++; + if ((token->type == TK_DONE || token->type == TK_ESAC + || token->type == TK_FI || token->type == TK_RBRACE + || token->type == TK_PAREN_CLOSE) && node->type == FNAME + && node->nest > 0) + node->nest--; + if ((token->type == TK_DONE || token->type == TK_ESAC + || token->type == TK_FI || token->type == TK_RBRACE + || token->type == TK_PAREN_CLOSE) && node->type == FNAME + && node->nest == 0) + node->full = 1; + return (add_cmd(&(*ast)->right, lst)); +} diff --git a/42sh/src/parser/add_loop.c b/42sh/src/parser/add_loop.c new file mode 100644 index 00000000..f58fee22 --- /dev/null +++ b/42sh/src/parser/add_loop.c @@ -0,0 +1,87 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* add_loop.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ariard +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/17 22:17:14 by ariard #+# #+# */ +/* Updated: 2017/03/22 15:29:37 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int isloop(t_btree **ast, t_list **lst) +{ + t_astnode *node; + t_token *token; + + node = NULL; + token = (*lst)->content; + if (*ast) + { + node = (*ast)->item; + if (node->type == TK_FOR && (token->type == TK_NEWLINE + || token->type == TK_SEMI) && node->pattern == 0) + return (1); + if (node->type == TK_FOR && (token->type == TK_WORD + || token->type == TK_NAME) && node->pattern == 0) + return (0); + if ((node->type == TK_NEWLINE || node->type == TK_SEMI + || node->type == TK_AMP || node->type == TK_PIPE + || node->type == TK_AND_IF || node->type == TK_OR_IF) + && isloop(&(*ast)->right, lst) == 1) + return (1); + if ((node->type == TK_WHILE || node->type == TK_UNTIL + || node->type == TK_FOR) && node->full == 0) + return (1); + } + return (0); +} + +int add_loop_cmd(t_btree **ast, t_list **lst) +{ + t_token *token; + t_astnode *node; + + token = (*lst)->content; + node = (*ast)->item; + if (token->type == TK_DO && node->type == TK_FOR) + node->pattern = 1; + if ((token->type == TK_WHILE || token->type == TK_UNTIL + || token->type == TK_FOR) && (node->type == TK_WHILE + || node->type == TK_UNTIL || node->type == TK_FOR)) + node->nest++; + if (token->type == TK_DONE && (node->type == TK_WHILE + || node->type == TK_UNTIL || node->type == TK_FOR) && node->nest > 0) + node->nest--; + else if (token->type == TK_DONE && (node->type == TK_WHILE + || node->type == TK_UNTIL || node->type == TK_FOR) && node->nest == 0) + return ((node->full = 1)); + if (token->type == TK_DO && node->nest == 0) + return (add_cmd(&(*ast)->right, lst)); + else if (!(*ast)->right && isloop(&(*ast)->left, lst) != 2) + return (add_cmd(&(*ast)->left, lst)); + else + return (add_cmd(&(*ast)->right, lst)); + return (0); +} + +int add_loop_sep(t_btree **ast, t_list **lst) +{ + t_astnode *node; + + node = NULL; + if (*ast) + { + node = (*ast)->item; + if (node->type == TK_FOR && node->pattern == 0) + return (0); + } + if (!(*ast)->right) + return (add_sep(&(*ast)->left, lst)); + else + return (add_sep(&(*ast)->right, lst)); + return (0); +} diff --git a/42sh/src/parser/add_number.c b/42sh/src/parser/add_number.c new file mode 100644 index 00000000..d685cd22 --- /dev/null +++ b/42sh/src/parser/add_number.c @@ -0,0 +1,51 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* add_number.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ariard +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/05 17:28:31 by ariard #+# #+# */ +/* Updated: 2017/03/22 15:32:16 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int isionumber(t_btree **ast, t_list **lst) +{ + t_token *token; + t_astnode *node; + + token = (*lst)->content; + if (*ast) + { + node = (*ast)->item; + if (node->type == CMD && token->type == TK_IO_NUMBER) + return (1); + } + if (!*ast) + { + if (token->type == TK_IO_NUMBER) + return (1); + } + return (0); +} + +int add_ionumber(t_btree **ast, t_list **lst) +{ + t_astnode *node; + t_token *token; + t_redir redir; + + if (!*ast) + gen_node(ast); + token = (*lst)->content; + node = (*ast)->item; + node->cache = node->type; + node->type = token->type; + redir_init(token->type, &redir); + redir.n = ft_atoi(token->data); + ft_lsteadd(&node->data.cmd.redir, ft_lstnew(&redir, sizeof(redir))); + return (0); +} diff --git a/42sh/src/parser/add_redir.c b/42sh/src/parser/add_redir.c new file mode 100644 index 00000000..ec189830 --- /dev/null +++ b/42sh/src/parser/add_redir.c @@ -0,0 +1,128 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* add_redir.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ariard +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/17 16:39:05 by ariard #+# #+# */ +/* Updated: 2017/03/24 17:24:01 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int isdir_sep(t_btree **ast, t_list **list) +{ + t_token *token; + t_astnode *node; + + token = (*list)->content; + if (*ast) + { + node = (*ast)->item; + if ((node->type == CMD || node->type == TK_IO_NUMBER + || node->type == TK_WHILE || node->type == TK_IF + || node->type == TK_FOR || node->type == SUBSHELL + || node->type == TK_CASE || node->type == TK_LBRACE + || node->type == TK_UNTIL) + && (token->type == TK_LESS || token->type == TK_GREAT + || token->type == TK_GREATAND || token->type == TK_LESSAND + || token->type == TK_DLESS || token->type == TK_DGREAT)) + return (1); + } + if (!*ast) + { + if (token->type == TK_LESS || token->type == TK_GREAT + || token->type == TK_GREATAND || token->type == TK_LESSAND + || token->type == TK_DLESS || token->type == TK_DGREAT) + return (1); + } + return (0); +} + +int isdir_word(t_btree **ast, t_list **list) +{ + t_astnode *node; + t_token *token; + + token = (*list)->content; + if (*ast) + { + node = (*ast)->item; + if (token->type == TK_WORD && node->type == REDIR) + { + if (node->cache != TK_NEWLINE) + node->type = node->cache; + else + node->type = CMD; + node->cache = 0; + return (1); + } + } + return (0); +} + +int add_redir_word(t_btree **ast, t_list **lst) +{ + t_astnode *node; + t_token *token; + t_redir *redir; + + token = (*lst)->content; + node = (*ast)->item; + if (node->data.cmd.redir) + { + redir = (ft_lstlast(node->data.cmd.redir))->content; + redir->word = ft_strdup(token->data); + } + return (0); +} + +static int add_redir_type_number(t_btree **ast, t_list **lst) +{ + t_redir *redir; + t_astnode *node; + t_token *token; + t_list **queue; + t_list *redir_lst; + + queue = &data_singleton()->parser.heredoc_queue; + token = (*lst)->content; + node = (*ast)->item; + redir_lst = ft_lstlast(node->data.cmd.redir); + redir = redir_lst->content; + redir->type = token->type; + if (token->type == TK_DLESS) + ft_lsteadd(queue, ft_lstnew(&redir_lst->content, sizeof(t_redir*))); + return (0); +} + +int add_redir_type(t_btree **ast, t_list **lst) +{ + t_astnode *node; + t_token *token; + t_redir redir; + t_list *redir_lst; + t_list **queue; + + queue = &data_singleton()->parser.heredoc_queue; + if (!*ast) + gen_node(ast); + token = (*lst)->content; + node = (*ast)->item; + if (!(node->type == TK_IO_NUMBER)) + { + redir_init(token->type, &redir); + redir_lst = ft_lstnew(&redir, sizeof(redir)); + ft_lsteadd(&node->data.cmd.redir, redir_lst); + if (token->type == TK_DLESS) + ft_lsteadd(queue, ft_lstnew(&redir_lst->content, sizeof(t_redir*))); + } + else + add_redir_type_number(ast, lst); + if (!node->cache) + node->cache = node->type; + node->type = REDIR; + return (0); +} diff --git a/42sh/src/parser/add_sep.c b/42sh/src/parser/add_sep.c new file mode 100644 index 00000000..aef1597e --- /dev/null +++ b/42sh/src/parser/add_sep.c @@ -0,0 +1,42 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* add_sep.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ariard +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/15 19:12:07 by ariard #+# #+# */ +/* Updated: 2017/03/22 15:30:32 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int add_sep(t_btree **ast, t_list **lst) +{ + t_token *token; + t_astnode *node; + t_btree *new_node; + + if (isloop(ast, lst)) + return (add_loop_sep(ast, lst)); + else if (iscondition(ast, lst)) + return (add_condition_sep(ast, lst)); + else if (iscase(ast, lst)) + return (add_sep(&(*ast)->right, lst)); + else if (issubshell(ast, lst)) + return (add_subshell_sep(ast, lst)); + else if (isfunc(ast, lst)) + return (add_subshell_sep(ast, lst)); + else if (isbang_sep(ast, lst)) + return (add_bang_sep(ast, lst)); + if (!*ast) + gen_node(ast); + token = (*lst)->content; + new_node = NULL; + gen_node(&new_node); + join_ast(ast, &new_node); + node = (new_node)->item; + node->type = token->type; + return (0); +} diff --git a/42sh/src/parser/add_subshell.c b/42sh/src/parser/add_subshell.c new file mode 100644 index 00000000..147901fe --- /dev/null +++ b/42sh/src/parser/add_subshell.c @@ -0,0 +1,62 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* add_subshell.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ariard +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/24 18:41:50 by ariard #+# #+# */ +/* Updated: 2017/03/24 17:02:29 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int issubshell(t_btree **ast, t_list **lst) +{ + t_astnode *node; + + (void)lst; + node = NULL; + if (*ast) + { + node = (*ast)->item; + if ((node->type == TK_NEWLINE || node->type == TK_SEMI + || node->type == TK_AMP || node->type == TK_PIPE + || node->type == TK_AND_IF || node->type == TK_OR_IF) + && issubshell(&(*ast)->right, lst) == 1) + return (1); + if (node->type == SUBSHELL && node->full == 0) + return (1); + if (node->type == TK_LBRACE && node->full == 0) + return (1); + } + return (0); +} + +int add_subshell_cmd(t_btree **ast, t_list **lst) +{ + t_token *token; + t_astnode *node; + + token = (*lst)->content; + node = (*ast)->item; + if ((token->type == SUBSHELL && node->type == SUBSHELL) + || (token->type == TK_LBRACE && node->type == TK_LBRACE)) + node->nest++; + if (((token->type == TK_PAREN_CLOSE && node->type == SUBSHELL) + || (token->type == TK_RBRACE && node->type == TK_LBRACE)) && node->nest > 0) + node->nest--; + if (token->type == TK_PAREN_CLOSE && node->type == SUBSHELL + && node->nest == 0) + return ((node->full = 1)); + else if (token->type == TK_RBRACE && node->type == TK_LBRACE + && node->nest == 0) + return ((node->full = 1)); + return (add_cmd(&(*ast)->right, lst)); +} + +int add_subshell_sep(t_btree **ast, t_list **lst) +{ + return (add_sep(&(*ast)->right, lst)); +} diff --git a/42sh/src/parser/aggregate_sym.c b/42sh/src/parser/aggregate_sym.c new file mode 100644 index 00000000..0e243252 --- /dev/null +++ b/42sh/src/parser/aggregate_sym.c @@ -0,0 +1,405 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* aggregate_sym.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ariard +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/11 15:58:38 by ariard #+# #+# */ +/* Updated: 2017/03/29 17:41:57 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static t_aggrematch g_aggrematch[] = +{ + {TK_WORD, CMD_SUFFIX, CMD_SUFFIX, 0}, + {TK_WORD, TK_PIPE, PATTERN, 0}, + {TK_WORD, TK_IN, FOR_WORDLIST, TK_IN}, + {TK_WORD, FOR_WORDLIST, FOR_WORDLIST, FOR_WORDLIST}, + {TK_SEMI, FOR_WORDLIST, SEQUENTIAL_SEP, 0}, + {TK_DSEMI, CMD_SUPERIOR, CLOSE_LIST, TK_PAREN_CLOSE}, + {TK_DSEMI, PIPE_SEMI_SEQUENCE, CLOSE_LIST, TK_PAREN_CLOSE}, + {TK_DSEMI, PIPE_CLOSE_SEQUENCE, CLOSE_LIST, TK_PAREN_CLOSE}, + {TK_PAREN_OPEN, TK_IN, PATTERN_CASE, 0}, + {TK_PAREN_OPEN, CASE_LIST_NS, PATTERN_CASE, 0}, + {TK_PAREN_OPEN, CMD_SUPERIOR, OPEN_FUNC, 0}, + {TK_ASSIGNMENT_WORD, CMD_PREFIX, CMD_PREFIX, 0}, + {TK_PIPE, CMD_SUPERIOR, SEQUENCE, CMD_SUPERIOR}, + {TK_PIPE, PIPE_SEMI_SEQUENCE, SEQUENCE, PIPE_SEMI_SEQUENCE}, + {TK_PIPE, PIPE_CLOSE_SEQUENCE, SEQUENCE, PIPE_CLOSE_SEQUENCE}, + {TK_FI, ELSE_PART, IF_CLAUSE, TK_IF}, + {TK_FI, COMPOUND_LIST, IF_CLAUSE, COMPLETE_CONDITION}, + {TK_FI, COMPLETE_CONDITION, IF_CLAUSE, COMPLETE_CONDITION}, + {TK_FI, CONDITION, IF_CLAUSE, COMPLETE_CONDITION}, + {TK_THEN, CONDITION, COMPLETE_CONDITION, CONDITION}, + {TK_DONE, CMD_SUPERIOR, DO_GROUP, TK_DO}, + {TK_DONE, COMPOUND_LIST, DO_GROUP, TK_DO}, + {TK_ESAC, TK_IN, CASE_CLAUSE, TK_CASE}, + {TK_ESAC, CASE_LIST_NS, CASE_CLAUSE, TK_CASE}, + {TK_PAREN_CLOSE, SUBSHELL, SUBSHELL, TK_PAREN_OPEN}, + {TK_PAREN_CLOSE, COMPOUND_LIST, SUBSHELL, TK_PAREN_OPEN}, + {TK_PAREN_CLOSE, CMD_SUPERIOR, SUBSHELL, TK_PAREN_OPEN}, + {TK_PAREN_CLOSE, PIPE_SEMI_SEQUENCE, SUBSHELL, TK_PAREN_OPEN}, + {TK_PAREN_CLOSE, PIPE_CLOSE_SEQUENCE, SUBSHELL, TK_PAREN_OPEN}, + {TK_PAREN_CLOSE, OPEN_FUNC, CLOSE_FUNC, OPEN_FUNC}, + {CLOSE_FUNC, CMD_SUPERIOR, FUNC_NAME, CMD_SUPERIOR}, + {TK_RBRACE, COMPOUND_LIST, BRACE_CLAUSE, TK_LBRACE}, + {TK_RBRACE, CMD_SUPERIOR, BRACE_CLAUSE, TK_LBRACE}, + {TK_RBRACE, PIPE_SEMI_SEQUENCE, BRACE_CLAUSE, TK_LBRACE}, + {TK_RBRACE, PIPE_CLOSE_SEQUENCE, BRACE_CLAUSE, TK_LBRACE}, + {TK_RBRACE, COMPOUND_LIST, BRACE_CLAUSE, TK_LBRACE}, + {TK_RBRACE, CMD_SUPERIOR, BRACE_CLAUSE, TK_LBRACE}, + {TK_AND_IF, CMD_SUPERIOR, AND_OR_MINOR, CMD_SUPERIOR}, + {TK_AND_IF, PIPE_CLOSE_SEQUENCE, AND_OR_MINOR, PIPE_CLOSE_SEQUENCE}, + {TK_AND_IF, PIPE_SEMI_SEQUENCE, AND_OR_MINOR, PIPE_SEMI_SEQUENCE}, + {TK_OR_IF, PIPE_SEMI_SEQUENCE, AND_OR_MINOR, PIPE_SEMI_SEQUENCE}, + {TK_OR_IF, CMD_SUPERIOR, AND_OR_MINOR, CMD_SUPERIOR}, + {TK_OR_IF, PIPE_CLOSE_SEQUENCE, AND_OR_MINOR, PIPE_CLOSE_SEQUENCE}, + {SEPARATOR_OP, CMD_SUPERIOR, SEPARATOR, 0}, + {SEPARATOR_OP, COMPOUND_LIST, SEPARATOR, 0}, + {SEPARATOR_OP, CASE_LIST_NS, SEPARATOR, 0}, + {SEPARATOR_OP, PIPE_SEMI_SEQUENCE, SEPARATOR, 0}, + {SEPARATOR_OP, PIPE_CLOSE_SEQUENCE, SEPARATOR, 0}, + {SEPARATOR, CMD_SUPERIOR, END_COMMAND, CMD_SUPERIOR}, + {SEPARATOR, CASE_LIST_NS, CASE_LIST_NS, CASE_LIST_NS}, + {SEPARATOR, COMPOUND_LIST, COMPOUND_LIST, COMPOUND_LIST}, + {SEPARATOR, PIPE_SEMI_SEQUENCE, PIPE_SEQUENCE, PIPE_SEMI_SEQUENCE}, + {SEPARATOR, PIPE_CLOSE_SEQUENCE, PIPE_SEQUENCE, PIPE_CLOSE_SEQUENCE}, + {LINEBREAK, SEPARATOR_OP, SEPARATOR, SEPARATOR_OP}, + {LINEBREAK, TK_SEMI, SEQUENTIAL_SEP, TK_SEMI}, + {LINEBREAK, TK_PAREN_CLOSE, FUNC, FNAME}, + {LINEBREAK, COMPLETE_COMMANDS, PROGRAM, LINEBREAK}, + {LINEBREAK, CMD_SUPERIOR, SEPARATOR_OP, 0}, + {LINEBREAK, PIPE_SEMI_SEQUENCE, PIPE_SEQUENCE, PIPE_SEMI_SEQUENCE}, + {LINEBREAK, PIPE_CLOSE_SEQUENCE, PIPE_SEQUENCE, PIPE_CLOSE_SEQUENCE}, + {LINEBREAK, COMPOUND_LIST, COMPOUND_LIST, COMPOUND_LIST}, + {LINEBREAK, CASE_LIST_NS, CASE_LIST_NS, CASE_LIST_NS}, + {NEWLINE_LIST, CMD_NAME, CMD_SUPERIOR, CMD_NAME}, + {NEWLINE_LIST, SEQUENTIAL_SEP, SEQUENTIAL_SEP, SEQUENTIAL_SEP}, + {NEWLINE_LIST, TK_DO, TK_DO, TK_DO}, + {NEWLINE_LIST, TK_PAREN_CLOSE, TK_PAREN_CLOSE, TK_PAREN_CLOSE}, + {NEWLINE_LIST, TK_PAREN_OPEN, TK_PAREN_OPEN, TK_PAREN_OPEN}, + {NEWLINE_LIST, TK_RBRACE, TK_RBRACE, TK_RBRACE}, + {NEWLINE_LIST, TK_LBRACE, TK_LBRACE, TK_LBRACE}, + {NEWLINE_LIST, TK_IN, TK_IN, TK_IN}, + {NEWLINE_LIST, TK_THEN, TK_THEN, TK_THEN}, + {NEWLINE_LIST, TK_IF, TK_IF, TK_IF}, + {NEWLINE_LIST, TK_ELIF, TK_ELIF, TK_ELIF}, + {NEWLINE_LIST, TK_ELSE, TK_ELSE, TK_ELSE}, + {NEWLINE_LIST, TK_WHILE, TK_WHILE, TK_WHILE}, + {NEWLINE_LIST, LOOP, LOOP, LOOP}, + {NEWLINE_LIST, TK_LBRACE, TK_LBRACE, TK_LBRACE}, + {NEWLINE_LIST, TK_UNTIL, TK_UNTIL, TK_UNTIL}, + {NEWLINE_LIST, CASE_LIST_NS, CASE_LIST_NS, CASE_LIST_NS}, + {NEWLINE_LIST, NEWLINE_LIST, NEWLINE_LIST, NEWLINE}, + {NEWLINE_LIST, NAME, SEQUENTIAL_SEP, 0}, + {NEWLINE_LIST, IN, SEQUENTIAL_SEP, 0}, + {NEWLINE_LIST, TERM, SEPARATOR, 0}, + {NEWLINE_LIST, SEQUENCE, SEQUENCE, SEQUENCE}, + {NEWLINE_LIST, COMPOUND_LIST, SEPARATOR, 0}, + {NEWLINE_LIST, FUNC_NAME, FUNC_NAME, FUNC_NAME}, + {NEWLINE_LIST, CASE_LIST_NS, SEPARATOR, 0}, + {NEWLINE_LIST, COMPLETE_CONDITION, COMPLETE_CONDITION, COMPLETE_CONDITION}, + {NEWLINE_LIST, CONDITION, CONDITION, CONDITION}, + {NEWLINE_LIST, COMPLETE_COMMANDS, LINEBREAK, 0}, + {NEWLINE_LIST, LINEBREAK, PROGRAM, LINEBREAK}, + {NEWLINE_LIST, FOR_WORDLIST, SEQUENTIAL_SEP, 0}, + {NEWLINE_LIST, PROGRAM, PROGRAM, PROGRAM}, + {SEQUENTIAL_SEP, FOR_WORDLIST, SEQUENTIAL_SEP, FOR_WORDLIST}, + {FILENAME, TK_LESS, IO_FILE, TK_LESS}, + {FILENAME, TK_LESSAND, IO_FILE, TK_LESSAND}, + {FILENAME, TK_GREAT, IO_FILE, TK_GREAT}, + {FILENAME, TK_GREATAND, IO_FILE, TK_GREATAND}, + {FILENAME, TK_DGREAT, IO_FILE, TK_DGREAT}, + {FILENAME, TK_LESSGREAT, IO_FILE, TK_LESSGREAT}, + {FILENAME, TK_CLOBBER, IO_FILE, TK_CLOBBER}, + {HERE_END, TK_DLESS, IO_HERE, TK_DLESS}, + {IO_FILE, TK_IO_NUMBER, IO_REDIRECT, TK_IO_NUMBER}, + {IO_FILE, ALL, IO_REDIRECT, 0}, + {IO_HERE, TK_IO_NUMBER, IO_REDIRECT, TK_IO_NUMBER}, + {IO_HERE, ALL, IO_REDIRECT, 0}, + {IO_REDIRECT, CMD_SUPERIOR, CMD_SUPERIOR, CMD_SUPERIOR}, + {IO_REDIRECT, PIPE_SEMI_SEQUENCE, PIPE_SEMI_SEQUENCE, PIPE_SEMI_SEQUENCE}, + {IO_REDIRECT, PIPE_CLOSE_SEQUENCE, PIPE_CLOSE_SEQUENCE, + PIPE_CLOSE_SEQUENCE}, + {IO_REDIRECT, COMPOUND_COMMAND, REDIRECT_LIST, REDIRECT_LIST}, + {IO_REDIRECT, CMD_SUFFIX, CMD_SUFFIX, CMD_SUFFIX}, + {IO_REDIRECT, CMD_NAME, CMD_SUFFIX, 0}, + {IO_REDIRECT, CMD_WORD, CMD_SUFFIX, 0}, + {IO_REDIRECT, CMD_PREFIX, CMD_PREFIX, CMD_PREFIX}, + {IO_REDIRECT, LINEBREAK, CMD_PREFIX, 0}, + {IO_REDIRECT, SEQUENCE, CMD_PREFIX, 0}, + {IO_REDIRECT, TK_PAREN_OPEN, CMD_PREFIX, 0}, + {IO_REDIRECT, TK_LBRACE, CMD_PREFIX, 0}, + {IO_REDIRECT, COMPLETE_COMMANDS, CMD_PREFIX, 0}, + {IO_REDIRECT, TK_BANG, CMD_PREFIX, TK_BANG}, + {IO_REDIRECT, SEPARATOR_OP, CMD_PREFIX, 0}, + {IO_REDIRECT, NEWLINE_LIST, CMD_PREFIX, 0}, + {IO_REDIRECT, TK_WHILE, CMD_PREFIX, 0}, + {IO_REDIRECT, TK_UNTIL, CMD_PREFIX, 0}, + {IO_REDIRECT, TK_DO, CMD_PREFIX, 0}, + {IO_REDIRECT, TK_THEN, CMD_PREFIX, TK_BANG}, + {IO_REDIRECT, TK_IF, CMD_PREFIX, 0}, + {IO_REDIRECT, TK_ELIF, CMD_PREFIX, 0}, + {IO_REDIRECT, TK_ELSE, CMD_PREFIX, 0}, + {IO_REDIRECT, TK_PAREN_CLOSE, CMD_PREFIX, 0}, + {REDIRECT_LIST, COMPOUND_COMMAND, COMPOUND_COMMAND, COMPOUND_COMMAND}, + {CMD_SUFFIX, CMD_WORD, SIMPLE_COMMAND, CMD_PREFIX}, + {CMD_SUFFIX, CMD_NAME, SIMPLE_COMMAND, CMD_NAME}, + {CMD_SUFFIX, CMD_SUPERIOR, CMD_SUPERIOR, CMD_SUPERIOR}, + {CMD_SUFFIX, COMPOUND_LIST, COMPOUND_LIST, COMPOUND_LIST}, + {CMD_SUFFIX, PIPE_SEMI_SEQUENCE, PIPE_SEMI_SEQUENCE, PIPE_SEMI_SEQUENCE}, + {CMD_SUFFIX, PIPE_CLOSE_SEQUENCE, PIPE_CLOSE_SEQUENCE, PIPE_CLOSE_SEQUENCE}, + {CMD_PREFIX, LINEBREAK, SIMPLE_COMMAND, 0}, + {CMD_PREFIX, SEQUENCE, SIMPLE_COMMAND, 0}, + {CMD_PREFIX, TK_PAREN_OPEN, SIMPLE_COMMAND, 0}, + {CMD_PREFIX, TK_LBRACE, SIMPLE_COMMAND, 0}, + {CMD_PREFIX, COMPLETE_COMMANDS, SIMPLE_COMMAND, 0}, + {CMD_PREFIX, TK_BANG, SIMPLE_COMMAND, TK_BANG}, + {CMD_PREFIX, SEPARATOR_OP, SIMPLE_COMMAND, 0}, + {CMD_PREFIX, NEWLINE_LIST, SIMPLE_COMMAND, 0}, + {CMD_PREFIX, TK_WHILE, SIMPLE_COMMAND, 0}, + {CMD_PREFIX, TK_UNTIL, SIMPLE_COMMAND, 0}, + {CMD_PREFIX, TK_DO, SIMPLE_COMMAND, 0}, + {CMD_PREFIX, TK_THEN, SIMPLE_COMMAND, TK_BANG}, + {CMD_PREFIX, TK_IF, SIMPLE_COMMAND, 0}, + {CMD_PREFIX, TK_ELIF, SIMPLE_COMMAND, 0}, + {CMD_PREFIX, TK_ELSE, SIMPLE_COMMAND, 0}, + {CMD_PREFIX, TK_PAREN_CLOSE, SIMPLE_COMMAND, 0}, + {CMD_PREFIX, COMPLETE_CONDITION, SIMPLE_COMMAND, 0}, + {CMD_PREFIX, CONDITION, SIMPLE_COMMAND, 0}, + {CMD_PREFIX, TK_PIPE, SIMPLE_COMMAND, 0}, + {CMD_PREFIX, SEQUENCE, SIMPLE_COMMAND, 0}, + {CMD_PREFIX, COMPOUND_LIST, SIMPLE_COMMAND, 0}, + {CMD_WORD, CMD_PREFIX, SIMPLE_COMMAND, CMD_PREFIX}, + {CMD_NAME, LINEBREAK, CMD_SUPERIOR, 0}, + {CMD_NAME, TK_PAREN_OPEN, CMD_SUPERIOR, 0}, + {CMD_NAME, TK_LBRACE, CMD_SUPERIOR, 0}, + {CMD_NAME, COMPLETE_COMMANDS, CMD_SUPERIOR, 0}, + {CMD_NAME, TK_BANG, CMD_SUPERIOR, TK_BANG}, + {CMD_NAME, SEPARATOR_OP, CMD_SUPERIOR, 0}, + {CMD_NAME, NEWLINE_LIST, CMD_SUPERIOR, 0}, + {CMD_NAME, TK_WHILE, CMD_SUPERIOR, 0}, + {CMD_NAME, TK_UNTIL, CMD_SUPERIOR, 0}, + {CMD_NAME, TK_DO, CMD_SUPERIOR, 0}, + {CMD_NAME, TK_PAREN_CLOSE, CMD_SUPERIOR, 0}, + {CMD_NAME, TK_IF, CMD_SUPERIOR, 0}, + {CMD_NAME, TK_ELIF, CMD_SUPERIOR, 0}, + {CMD_NAME, TK_ELSE, CMD_SUPERIOR, 0}, + {CMD_NAME, TK_THEN, CMD_SUPERIOR, 0}, + {CMD_NAME, COMPOUND_LIST, CMD_SUPERIOR, 0}, + {CMD_NAME, CASE_LIST_NS, CMD_SUPERIOR, 0}, + {CMD_NAME, COMPLETE_CONDITION, CMD_SUPERIOR, 0}, + {CMD_NAME, CONDITION, CMD_SUPERIOR, 0}, + {CMD_NAME, TK_PIPE, CMD_SUPERIOR, 0}, + {CMD_NAME, SEQUENCE, CMD_SUPERIOR, 0}, + {CMD_NAME, AND_OR_MAJOR, CMD_SUPERIOR, 0}, + {CMD_SUPERIOR, SEQUENCE, PIPE_SEMI_SEQUENCE, SEQUENCE}, + {SIMPLE_COMMAND, ALL, COMMAND, 0}, + {DO_GROUP, NAME, FOR_CLAUSE, TK_FOR}, + {DO_GROUP, IN, FOR_CLAUSE, TK_FOR}, + {DO_GROUP, SEQUENTIAL_SEP, FOR_CLAUSE, TK_FOR}, + {DO_GROUP, CMD_SUPERIOR, LOOP, CMD_SUPERIOR}, + {DO_GROUP, COMPOUND_LIST, LOOP, COMPOUND_LIST}, + {BRACE_GROUP, ALL, COMPOUND_COMMAND, 0}, + {FUNCTION_BODY, FUNC, FUNCTION_DEFINITION, 0}, + {FUNCTION_DEFINITION, ALL, COMMAND, 0}, + {LOOP, TK_WHILE, WHILE_CLAUSE, TK_WHILE}, + {LOOP, TK_UNTIL, UNTIL_CLAUSE, TK_UNTIL}, + {UNTIL_CLAUSE, ALL, COMPOUND_COMMAND, 0}, + {WHILE_CLAUSE, ALL, COMPOUND_COMMAND, 0}, + {IF_CLAUSE, ALL, COMPOUND_COMMAND, 0}, + {CASE_LIST_NS, TK_IN, TK_IN, TK_IN}, + {CASE_CLAUSE, ALL, COMPOUND_COMMAND, 0}, + {FOR_CLAUSE, ALL, COMPOUND_COMMAND, 0}, + {COMPOUND_LIST, TK_IF, CONDITION, TK_IF}, + {COMPOUND_LIST, TK_THEN, CONDITION, TK_THEN}, + {COMPOUND_LIST, TK_PAREN_CLOSE, CLOSE_LIST, TK_PAREN_CLOSE}, + {COMPOUND_LIST, COMPLETE_CONDITION, COMPLETE_CONDITION, COMPLETE_CONDITION}, + {COMPOUND_LIST, CONDITION, CONDITION, CONDITION}, + {COMPOUND_LIST, COMPOUND_LIST, COMPOUND_LIST, COMPOUND_LIST}, + {COMPOUND_LIST, CASE_LIST_NS, CASE_LIST_NS, CASE_LIST_NS}, + {CLOSE_LIST, PATTERN, CASE_LIST_NS, PATTERN_CASE}, + {CLOSE_LIST, FUNC_NAME, FUNCTION_DEFINITION, FUNC_NAME}, + {SUBSHELL, ALL, COMPOUND_COMMAND, 0}, + {BRACE_CLAUSE, ALL, COMPOUND_COMMAND, 0}, + {COMPOUND_COMMAND, FUNC_NAME, COMMAND, FUNC_NAME}, + {AND_OR_MINOR, PIPE_SEMI_SEQUENCE, AND_OR_MAJOR, PIPE_SEMI_SEQUENCE}, + {AND_OR_MINOR, PIPE_CLOSE_SEQUENCE, AND_OR_MAJOR, PIPE_CLOSE_SEQUENCE}, + {AND_OR_MINOR, COMPLETE_CONDITION, AND_OR_MAJOR, 0}, + {AND_OR_MINOR, TK_DO, AND_OR_MAJOR, 0}, + {AND_OR_MINOR, TK_PAREN_CLOSE, AND_OR_MAJOR, 0}, + {AND_OR_MINOR, LINEBREAK, AND_OR_MAJOR, 0}, + {AND_OR_MINOR, TK_PAREN_OPEN, AND_OR_MAJOR, 0}, + {AND_OR_MINOR, TK_LBRACE, AND_OR_MAJOR, 0}, + {AND_OR_MINOR, COMPOUND_LIST, AND_OR_MAJOR, 0}, + {AND_OR_MINOR, COMPLETE_COMMANDS, AND_OR_MAJOR, 0}, + {AND_OR_MINOR, AND_OR_MAJOR, AND_OR_MAJOR, 0}, + {AND_OR_MINOR, TK_BANG, AND_OR_MAJOR, TK_BANG}, + {COMMAND, SEQUENCE, PIPE_SEMI_SEQUENCE, 0}, + {COMMAND, COMPOUND_LIST, PIPE_SEMI_SEQUENCE, 0}, + {COMMAND, CASE_LIST_NS, PIPE_SEMI_SEQUENCE, 0}, + {COMMAND, TK_WHILE, PIPE_SEMI_SEQUENCE, 0}, + {COMMAND, TK_UNTIL, PIPE_SEMI_SEQUENCE, 0}, + {COMMAND, TK_DO, PIPE_SEMI_SEQUENCE, 0}, + {COMMAND, TK_PAREN_CLOSE, PIPE_SEMI_SEQUENCE, 0}, + {COMMAND, TK_IF, PIPE_SEMI_SEQUENCE, 0}, + {COMMAND, TK_THEN, PIPE_SEMI_SEQUENCE, 0}, + {COMMAND, TK_ELIF, PIPE_SEMI_SEQUENCE, 0}, + {COMMAND, TK_ELSE, PIPE_SEMI_SEQUENCE, 0}, + {COMMAND, TK_BANG, PIPE_SEMI_SEQUENCE, TK_BANG}, + {COMMAND, SEPARATOR_OP, PIPE_SEMI_SEQUENCE, 0}, + {COMMAND, NEWLINE_LIST, PIPE_SEMI_SEQUENCE, 0}, + {COMMAND, LINEBREAK, PIPE_SEMI_SEQUENCE, 0}, + {COMMAND, TK_BANG, PIPE_SEMI_SEQUENCE, TK_BANG}, + {COMMAND, TK_PAREN_OPEN, PIPE_SEMI_SEQUENCE, 0}, + {COMMAND, TK_LBRACE, PIPE_SEMI_SEQUENCE, 0}, + {COMMAND, COMPLETE_COMMANDS, PIPE_SEMI_SEQUENCE, 0}, + {COMMAND, AND_OR_MAJOR, PIPE_SEMI_SEQUENCE, 0}, + {COMMAND, COMPLETE_CONDITION, PIPE_SEMI_SEQUENCE, 0}, + {COMMAND, CONDITION, PIPE_SEMI_SEQUENCE, 0}, + {COMPOUND_COMMAND, SEQUENCE, PIPE_CLOSE_SEQUENCE, 0}, + {COMPOUND_COMMAND, COMPOUND_LIST, PIPE_CLOSE_SEQUENCE, 0}, + {COMPOUND_COMMAND, CASE_LIST_NS, PIPE_CLOSE_SEQUENCE, 0}, + {COMPOUND_COMMAND, TK_WHILE, PIPE_CLOSE_SEQUENCE, 0}, + {COMPOUND_COMMAND, TK_UNTIL, PIPE_CLOSE_SEQUENCE, 0}, + {COMPOUND_COMMAND, TK_DO, PIPE_CLOSE_SEQUENCE, 0}, + {COMPOUND_COMMAND, TK_PAREN_CLOSE, PIPE_CLOSE_SEQUENCE, 0}, + {COMPOUND_COMMAND, TK_IF, PIPE_CLOSE_SEQUENCE, 0}, + {COMPOUND_COMMAND, TK_THEN, PIPE_CLOSE_SEQUENCE, 0}, + {COMPOUND_COMMAND, TK_ELIF, PIPE_CLOSE_SEQUENCE, 0}, + {COMPOUND_COMMAND, TK_ELSE, PIPE_CLOSE_SEQUENCE, 0}, + {COMPOUND_COMMAND, TK_BANG, PIPE_CLOSE_SEQUENCE, TK_BANG}, + {COMPOUND_COMMAND, SEPARATOR_OP, PIPE_CLOSE_SEQUENCE, 0}, + {COMPOUND_COMMAND, NEWLINE_LIST, PIPE_CLOSE_SEQUENCE, 0}, + {COMPOUND_COMMAND, LINEBREAK, PIPE_CLOSE_SEQUENCE, 0}, + {COMPOUND_COMMAND, TK_BANG, PIPE_CLOSE_SEQUENCE, TK_BANG}, + {COMPOUND_COMMAND, TK_PAREN_OPEN, PIPE_CLOSE_SEQUENCE, 0}, + {COMPOUND_COMMAND, TK_LBRACE, PIPE_CLOSE_SEQUENCE, 0}, + {COMPOUND_COMMAND, COMPLETE_COMMANDS, PIPE_CLOSE_SEQUENCE, 0}, + {COMPOUND_COMMAND, AND_OR_MAJOR, PIPE_CLOSE_SEQUENCE, 0}, + {COMPOUND_COMMAND, COMPLETE_CONDITION, PIPE_CLOSE_SEQUENCE, 0}, + {COMPOUND_COMMAND, CONDITION, PIPE_CLOSE_SEQUENCE, 0}, + {END_COMMAND, SEQUENCE, PIPE_SEQUENCE, SEQUENCE}, + {END_COMMAND, PIPE_SEMI_SEQUENCE, PIPE_SEQUENCE, PIPE_SEMI_SEQUENCE}, + {END_COMMAND, AND_OR_MAJOR, AND_OR, AND_OR_MAJOR}, + {END_COMMAND, TK_WHILE, PIPE_SEQUENCE, 0}, + {END_COMMAND, TK_WHILE, PIPE_SEQUENCE, 0}, + {END_COMMAND, TK_UNTIL, PIPE_SEQUENCE, 0}, + {END_COMMAND, LINEBREAK, PIPE_SEQUENCE, 0}, + {END_COMMAND, TK_BANG, PIPE_SEQUENCE, TK_BANG}, + {END_COMMAND, TK_PAREN_OPEN, PIPE_SEQUENCE, 0}, + {END_COMMAND, TK_LBRACE, PIPE_SEQUENCE, 0}, + {END_COMMAND, COMPLETE_COMMANDS, PIPE_SEQUENCE, 0}, + {END_COMMAND, TK_DO, PIPE_SEQUENCE, 0}, + {END_COMMAND, TK_PAREN_CLOSE, PIPE_SEQUENCE, 0}, + {END_COMMAND, TK_IF, PIPE_SEQUENCE, 0}, + {END_COMMAND, TK_ELIF, PIPE_SEQUENCE, 0}, + {END_COMMAND, TK_THEN, PIPE_SEQUENCE, 0}, + {END_COMMAND, TK_ELSE, PIPE_SEQUENCE, 0}, + {END_COMMAND, COMPLETE_CONDITION, PIPE_SEQUENCE, 0}, + {END_COMMAND, CONDITION, PIPE_SEQUENCE, 0}, + {END_COMMAND, COMPOUND_LIST, COMPOUND_LIST, COMPOUND_LIST}, + {END_COMMAND, CASE_LIST_NS, CASE_LIST_NS, CASE_LIST_NS}, + {PIPE_SEMI_SEQUENCE, SEQUENCE, PIPE_SEMI_SEQUENCE, SEQUENCE}, + {PIPE_CLOSE_SEQUENCE, SEQUENCE, PIPE_CLOSE_SEQUENCE, SEQUENCE}, + {PIPE_SEQUENCE, TK_WHILE, PIPELINE, 0}, + {PIPE_SEQUENCE, TK_UNTIL, PIPELINE, 0}, + {PIPE_SEQUENCE, TK_BANG, PIPELINE, TK_BANG}, + {PIPE_SEQUENCE, SEPARATOR_OP, PIPELINE, 0}, + {PIPE_SEQUENCE, NEWLINE_LIST, PIPELINE, 0}, + {PIPE_SEQUENCE, LINEBREAK, PIPELINE, 0}, + {PIPE_SEQUENCE, TK_PAREN_OPEN, PIPELINE, 0}, + {PIPE_SEQUENCE, TK_LBRACE, PIPELINE, 0}, + {PIPE_SEQUENCE, COMPLETE_COMMANDS, PIPELINE, 0}, + {PIPE_SEQUENCE, AND_OR_MAJOR, PIPELINE, 0}, + {PIPE_SEQUENCE, TK_DO, PIPELINE, 0}, + {PIPE_SEQUENCE, TK_PAREN_CLOSE, PIPELINE, 0}, + {PIPE_SEQUENCE, TK_IF, PIPELINE, 0}, + {PIPE_SEQUENCE, TK_ELIF, PIPELINE, 0}, + {PIPE_SEQUENCE, TK_THEN, PIPELINE, 0}, + {PIPE_SEQUENCE, TK_ELSE, PIPELINE, 0}, + {PIPE_SEQUENCE, COMPOUND_LIST, PIPELINE, 0}, + {PIPE_SEQUENCE, CASE_LIST_NS, PIPELINE, 0}, + {PIPE_SEQUENCE, COMPLETE_CONDITION, PIPELINE, 0}, + {PIPE_SEQUENCE, CONDITION, PIPELINE, 0}, + {PIPELINE, TK_WHILE, AND_OR, 0}, + {PIPELINE, TK_UNTIL, AND_OR, 0}, + {PIPELINE, TK_DO, AND_OR, 0}, + {PIPELINE, TK_PAREN_CLOSE, AND_OR, 0}, + {PIPELINE, TK_IF, AND_OR, 0}, + {PIPELINE, TK_IF, AND_OR, 0}, + {PIPELINE, TK_ELIF, AND_OR, 0}, + {PIPELINE, TK_THEN, AND_OR, 0}, + {PIPELINE, TK_ELSE, AND_OR, 0}, + {PIPELINE, COMPOUND_LIST, AND_OR, 0}, + {PIPELINE, CASE_LIST_NS, AND_OR, 0}, + {PIPELINE, LINEBREAK, AND_OR, 0}, + {PIPELINE, TK_BANG, AND_OR, TK_BANG}, + {PIPELINE, TK_PAREN_OPEN, AND_OR, 0}, + {PIPELINE, TK_LBRACE, AND_OR, 0}, + {PIPELINE, COMPLETE_COMMANDS, AND_OR, 0}, + {PIPELINE, SEPARATOR_OP, AND_OR, 0}, + {PIPELINE, COMPLETE_CONDITION, AND_OR, 0}, + {PIPELINE, CONDITION, AND_OR, 0}, + {PIPELINE, AND_OR_MAJOR, AND_OR, AND_OR_MAJOR}, + {AND_OR_MAJOR, AND_OR_MAJOR, AND_OR_MAJOR, AND_OR_MAJOR}, + {AND_OR, TK_DO, COMPOUND_LIST, 0}, + {AND_OR, TK_PAREN_CLOSE, COMPOUND_LIST, 0}, + {AND_OR, TK_WHILE, COMPOUND_LIST, 0}, + {AND_OR, TK_UNTIL, COMPOUND_LIST, 0}, + {AND_OR, TK_IF, COMPOUND_LIST, 0}, + {AND_OR, TK_ELIF, COMPOUND_LIST, 0}, + {AND_OR, TK_THEN, COMPOUND_LIST, 0}, + {AND_OR, TK_ELSE, COMPOUND_LIST, 0}, + {AND_OR, COMPOUND_LIST, COMPOUND_LIST, 0}, + {AND_OR, TK_PAREN_OPEN, COMPOUND_LIST, 0}, + {AND_OR, TK_LBRACE, COMPOUND_LIST, 0}, + {AND_OR, CASE_LIST_NS, CASE_LIST_NS, 0}, + {AND_OR, COMPLETE_CONDITION, COMPOUND_LIST, 0}, + {AND_OR, CONDITION, COMPOUND_LIST, 0}, + {AND_OR, SEPARATOR_OP, LIST, LIST}, + {AND_OR, NEWLINE_LIST, LIST, 0}, + {AND_OR, LINEBREAK, LIST, 0}, + {AND_OR, TK_BANG, LIST, TK_BANG}, + {AND_OR, TK_LBRACE, LIST, 0}, + {AND_OR, COMPLETE_COMMANDS, LIST, 0}, + {LIST, NEWLINE_LIST, COMPLETE_COMMAND, 0}, + {LIST, LINEBREAK, COMPLETE_COMMAND, 0}, + {LIST, COMPLETE_COMMANDS, COMPLETE_COMMAND, 0}, + {COMPLETE_COMMAND, NEWLINE_LIST, COMPLETE_COMMANDS, COMPLETE_COMMANDS}, + {COMPLETE_COMMAND, LINEBREAK, COMPLETE_COMMANDS, 0}, + {COMPLETE_COMMAND, COMPLETE_COMMANDS, COMPLETE_COMMANDS, 0}, + {COMPLETE_COMMANDS, COMPLETE_COMMANDS, COMPLETE_COMMANDS, + COMPLETE_COMMANDS}, + {0, 0, 0, 0}, +}; + +int aggregate_sym(t_list **stack, t_sym *new_sym, t_parstate *state) +{ + t_sym *head; + int i; + + if (!*stack || !new_sym || !*new_sym || !*state) + return (1); + i = -1; + head = (*stack)->content; + while (g_aggrematch[++i].top) + if (*new_sym == g_aggrematch[i].top + && MATCH_STACK(*head, g_aggrematch[i].under)) + { + *new_sym = g_aggrematch[i].new_sym; + if (g_aggrematch[i].erase_sym) + { + pop_stack(stack, g_aggrematch[i].erase_sym); + head = (*stack)->content; + } + if (eval_sym(stack, *new_sym) && !(*state = ERROR)) + return (1); + aggregate_sym(stack, new_sym, state); + return (0); + } + return (0); +} diff --git a/42sh/src/parser/build_tree.c b/42sh/src/parser/build_tree.c new file mode 100644 index 00000000..f10c604d --- /dev/null +++ b/42sh/src/parser/build_tree.c @@ -0,0 +1,99 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* build_tree.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ariard +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/15 18:32:59 by ariard #+# #+# */ +/* Updated: 2017/03/29 16:04:00 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static t_treematch g_treematch[] = +{ + {TK_WORD, &add_cmd}, + {TK_PIPE, &add_sep}, + {TK_BANG, &add_cmd}, + {TK_SEMI, &add_sep}, + {TK_GREAT, &add_cmd}, + {TK_LESS, &add_cmd}, + {TK_GREATAND, &add_cmd}, + {TK_LESSAND, &add_cmd}, + {TK_DGREAT, &add_cmd}, + {TK_DLESS, &add_cmd}, + {TK_IO_NUMBER, &add_cmd}, + {TK_OR_IF, &add_sep}, + {TK_AND_IF, &add_sep}, + {TK_AMP, &add_sep}, + {TK_WHILE, &add_cmd}, + {TK_UNTIL, &add_cmd}, + {TK_DO, &add_cmd}, + {TK_DONE, &add_cmd}, + {TK_IF, &add_cmd}, + {TK_ELIF, &add_cmd}, + {TK_ELSE, &add_cmd}, + {TK_THEN, &add_cmd}, + {TK_FI, &add_cmd}, + {TK_NEWLINE, &add_sep}, + {TK_CASE, &add_cmd}, + {TK_ESAC, &add_cmd}, + {TK_IN, &add_cmd}, + {TK_DSEMI, &add_cmd}, + {TK_PAREN_OPEN, &add_cmd}, + {TK_PAREN_CLOSE, &add_cmd}, + {TK_FOR, &add_cmd}, + {TK_NAME, &add_cmd}, + {TK_ASSIGNMENT_WORD, &add_cmd}, + {SUBSHELL, &add_cmd}, + {TK_LBRACE, &add_cmd}, + {TK_RBRACE, &add_cmd}, + {CLOSE_LIST, &add_cmd}, + {0, NULL}, +}; + +static int isseparator(t_token *token, int cache) +{ + if (token->type == TK_NEWLINE && (cache == TK_WHILE || cache == TK_DO + || cache == TK_NEWLINE || cache == TK_THEN || cache == TK_IN + || cache == TK_DSEMI || cache == SUBSHELL || cache == TK_ELIF + || cache == TK_ELSE || cache == TK_ELSE || cache == TK_CASE + || cache == TK_FOR || cache == TK_UNTIL)) + return (0); + return (1); +} + +static int check_cache(t_token *token, int cache) +{ + if (token->type == TK_ASSIGNMENT_WORD && cache == TK_WORD) + token->type = TK_WORD; + if (token->type == TK_PAREN_OPEN && cache != TK_IN && cache != TK_DSEMI + && cache != TK_WORD) + token->type = SUBSHELL; + if (token->type == TK_PAREN_CLOSE && cache == TK_PAREN_OPEN) + token->type = OTHER; + return (0); +} + +int build_tree(t_btree **ast, t_list **lst, t_parser *parser) +{ + int i; + t_token *token; + + i = 0; + token = (*lst)->content; + check_cache(token, parser->cache); + while (g_treematch[i].type) + { + if ((isseparator(token, parser->cache) && + g_treematch[i].type == token->type)) + { + parser->cache = token->type; + return (g_treematch[i].add(ast, lst)); + } + i++; + } + return (0); +} diff --git a/42sh/src/parser/do_parser_routine.c b/42sh/src/parser/do_parser_routine.c new file mode 100644 index 00000000..cbb71929 --- /dev/null +++ b/42sh/src/parser/do_parser_routine.c @@ -0,0 +1,37 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* do_parser_routine.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: wescande +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/19 14:24:14 by wescande #+# #+# */ +/* Updated: 2017/03/28 07:50:46 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int do_parser_routine(t_list **token, t_btree **ast) +{ + t_data *data; + + data = data_singleton(); + if (insert_newline(token)) + return (1); + if (data->parser.state == SUCCESS && stack_init(&data->parser)) + exit(1); + if (ft_parse(ast, token, &data->parser)) + exit(1); + if (data->parser.state != ERROR && + (data->lexer.state = data->parser.heredoc_queue ? HEREDOC : DEFAULT)) + return (0); + if (data->parser.state == ERROR) + { + error_syntax(token); + return (1); + } + else if (data->parser.state == SUCCESS) + return (2); + return (0); +} diff --git a/42sh/src/parser/error_syntax.c b/42sh/src/parser/error_syntax.c new file mode 100644 index 00000000..afcf4c95 --- /dev/null +++ b/42sh/src/parser/error_syntax.c @@ -0,0 +1,84 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* error_syntax.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ariard +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/09 20:15:35 by ariard #+# #+# */ +/* Updated: 2017/03/17 18:08:11 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +#define SYNTERR_0 "{red}syntax error near unexpected token `%s'{eoc}\n" +#define SYNTERR_1 "{red}syntax error near unexpected EOF{eoc}" + +static t_errormatch g_errormatch[] = +{ + {TK_NEWLINE, "newline"}, + {TK_SEMI, ";"}, + {TK_DSEMI, ";;"}, + {TK_PIPE, "|"}, + {TK_AMP, "&"}, + {TK_LESS, "<"}, + {TK_GREAT, ">"}, + {TK_DGREAT, ">>"}, + {TK_LESSAND, "<&"}, + {TK_GREATAND, ">&"}, + {TK_LESSGREAT, "<>"}, + {TK_CLOBBER, ">|"}, + {TK_DLESS, "<<"}, + {TK_DLESSDASH, "<<-"}, + {TK_AND_IF, "&&"}, + {TK_OR_IF, "||"}, + {TK_IF, "if"}, + {TK_THEN, "then"}, + {TK_ELSE, "else"}, + {TK_ELIF, "elif"}, + {TK_FI, "fi"}, + {TK_DO, "do"}, + {TK_DONE, "done"}, + {TK_CASE, "case"}, + {TK_ESAC, "esac"}, + {TK_WHILE, "while"}, + {TK_UNTIL, "until"}, + {TK_FOR, "for"}, + {TK_LBRACE, "{"}, + {TK_RBRACE, "}"}, + {TK_PAREN_OPEN, "("}, + {TK_PAREN_CLOSE, ")"}, + {TK_BANG, "!"}, + {TK_IN, "in"}, + {0, NULL}, +}; + +int error_syntax(t_list **lst) +{ + t_token *token; + int i; + + if (!*lst) + return (0); + token = (*lst)->content; + i = 0; + while (g_errormatch[i].token) + { + if (g_errormatch[i].token == token->type) + { + ft_dprintf(2, SYNTERR_0, g_errormatch[i].error); + return (0); + } + i++; + } + ft_dprintf(2, SYNTERR_0, + token->data); + return (0); +} + +int error_eof(void) +{ + ft_dprintf(2, SYNTERR_1); + return (1); +} diff --git a/42sh/src/parser/eval_sym.c b/42sh/src/parser/eval_sym.c new file mode 100644 index 00000000..183703eb --- /dev/null +++ b/42sh/src/parser/eval_sym.c @@ -0,0 +1,1311 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* eval_sym.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ariard +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/11 16:11:21 by ariard #+# #+# */ +/* Updated: 2017/03/29 17:41:06 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static t_stackmatch g_stackmatch[] = +{ + {TK_WORD, CMD_SUFFIX}, + {TK_WORD, TK_PIPE}, + {TK_WORD, TK_CASE}, + {TK_WORD, WORDLIST}, + {TK_WORD, LINEBREAK}, + {TK_WORD, TK_BANG}, + {TK_WORD, TK_PAREN_OPEN}, + {TK_WORD, TK_LBRACE}, + {TK_WORD, COMPLETE_COMMANDS}, + {TK_WORD, TK_IN}, + {TK_WORD, FOR_WORDLIST}, + {TK_ASSIGNMENT_WORD, CMD_PREFIX}, + {TK_IO_NUMBER, REDIRECT_LIST}, + {TK_IO_NUMBER, CMD_SUFFIX}, + {TK_IO_NUMBER, CMD_PREFIX}, + {TK_IO_NUMBER, CMD_NAME}, + {TK_IO_NUMBER, CMD_WORD}, + {TK_IO_NUMBER, LINEBREAK}, + {TK_IO_NUMBER, TK_BANG}, + {TK_IO_NUMBER, TK_PAREN_OPEN}, + {TK_IO_NUMBER, TK_LBRACE}, + {TK_IO_NUMBER, COMPLETE_COMMANDS}, + {TK_IO_NUMBER, SEPARATOR_OP}, + {TK_IO_NUMBER, NEWLINE_LIST}, + {TK_IO_NUMBER, PIPE_SEMI_SEQUENCE}, + {TK_IO_NUMBER, PIPE_CLOSE_SEQUENCE}, + {TK_IO_NUMBER, SEQUENCE}, + {TK_IO_NUMBER, CMD_SUPERIOR}, + {TK_IO_NUMBER, AND_OR_MAJOR}, + {TK_IO_NUMBER, TK_WHILE}, + {TK_IO_NUMBER, TK_UNTIL}, + {TK_IO_NUMBER, TK_IF}, + {TK_IO_NUMBER, TK_DO}, + {TK_IO_NUMBER, TK_ELIF}, + {TK_IO_NUMBER, TK_THEN}, + {TK_IO_NUMBER, TK_PAREN_CLOSE}, + {TK_IO_NUMBER, COMPLETE_CONDITION}, + {TK_IO_NUMBER, CONDITION}, + {TK_IO_NUMBER, COMPOUND_LIST}, + {TK_AND_IF, AND_OR}, + {TK_AND_IF, CMD_SUPERIOR}, + {TK_AND_IF, PIPE_SEMI_SEQUENCE}, + {TK_AND_IF, PIPE_CLOSE_SEQUENCE}, + {TK_AND_IF, COMPOUND_LIST}, + {TK_OR_IF, AND_OR}, + {TK_OR_IF, CMD_SUPERIOR}, + {TK_OR_IF, PIPE_SEMI_SEQUENCE}, + {TK_OR_IF, PIPE_CLOSE_SEQUENCE}, + {TK_OR_IF, COMPOUND_LIST}, + {TK_DSEMI, LINEBREAK}, + {TK_DSEMI, TK_BANG}, + {TK_DSEMI, COMPLETE_COMMANDS}, + {TK_DSEMI, COMPOUND_LIST}, + {TK_DSEMI, CASE_LIST_NS}, + {TK_DSEMI, CMD_SUPERIOR}, + {TK_DSEMI, PIPE_SEMI_SEQUENCE}, + {TK_DSEMI, PIPE_CLOSE_SEQUENCE}, + {TK_LESS, TK_IO_NUMBER}, + {TK_LESS, REDIRECT_LIST}, + {TK_LESS, CMD_SUFFIX}, + {TK_LESS, CMD_PREFIX}, + {TK_LESS, CMD_WORD}, + {TK_LESS, CMD_NAME}, + {TK_LESS, LINEBREAK}, + {TK_LESS, TK_PAREN_OPEN}, + {TK_LESS, TK_LBRACE}, + {TK_LESS, COMPLETE_COMMANDS}, + {TK_LESS, TK_BANG}, + {TK_LESS, SEPARATOR_OP}, + {TK_LESS, NEWLINE_LIST}, + {TK_LESS, PIPE_SEMI_SEQUENCE}, + {TK_LESS, PIPE_CLOSE_SEQUENCE}, + {TK_LESS, SEQUENCE}, + {TK_LESS, CMD_SUPERIOR}, + {TK_LESS, AND_OR_MAJOR}, + {TK_LESS, TK_WHILE}, + {TK_LESS, TK_UNTIL}, + {TK_LESS, TK_IF}, + {TK_LESS, TK_DO}, + {TK_LESS, TK_ELIF}, + {TK_LESS, TK_THEN}, + {TK_LESS, TK_PAREN_CLOSE}, + {TK_LESS, COMPLETE_CONDITION}, + {TK_LESS, CONDITION}, + {TK_LESS, COMPOUND_LIST}, + {TK_LESS, CMD_SUPERIOR}, + {TK_LESS, AND_OR_MAJOR}, + {TK_GREAT, TK_IO_NUMBER}, + {TK_GREAT, REDIRECT_LIST}, + {TK_GREAT, CMD_SUFFIX}, + {TK_GREAT, CMD_PREFIX}, + {TK_GREAT, CMD_WORD}, + {TK_GREAT, CMD_NAME}, + {TK_GREAT, LINEBREAK}, + {TK_GREAT, TK_BANG}, + {TK_GREAT, TK_PAREN_OPEN}, + {TK_GREAT, TK_LBRACE}, + {TK_GREAT, COMPLETE_COMMANDS}, + {TK_GREAT, SEPARATOR_OP}, + {TK_GREAT, NEWLINE_LIST}, + {TK_GREAT, PIPE_SEMI_SEQUENCE}, + {TK_GREAT, PIPE_CLOSE_SEQUENCE}, + {TK_GREAT, SEQUENCE}, + {TK_GREAT, CMD_SUPERIOR}, + {TK_GREAT, AND_OR_MAJOR}, + {TK_GREAT, TK_WHILE}, + {TK_GREAT, TK_UNTIL}, + {TK_GREAT, TK_IF}, + {TK_GREAT, TK_DO}, + {TK_GREAT, TK_ELIF}, + {TK_GREAT, TK_THEN}, + {TK_GREAT, TK_PAREN_CLOSE}, + {TK_GREAT, COMPLETE_CONDITION}, + {TK_GREAT, CONDITION}, + {TK_GREAT, COMPOUND_LIST}, + {TK_GREAT, CMD_SUPERIOR}, + {TK_GREAT, AND_OR_MAJOR}, + {TK_DLESS, TK_IO_NUMBER}, + {TK_DLESS, REDIRECT_LIST}, + {TK_DLESS, CMD_SUFFIX}, + {TK_DLESS, CMD_PREFIX}, + {TK_DLESS, CMD_WORD}, + {TK_DLESS, CMD_NAME}, + {TK_DLESS, LINEBREAK}, + {TK_DLESS, TK_PAREN_OPEN}, + {TK_DLESS, TK_LBRACE}, + {TK_DLESS, COMPLETE_COMMANDS}, + {TK_DLESS, TK_BANG}, + {TK_DLESS, SEPARATOR_OP}, + {TK_DLESS, NEWLINE_LIST}, + {TK_DLESS, PIPE_SEMI_SEQUENCE}, + {TK_DLESS, PIPE_CLOSE_SEQUENCE}, + {TK_DLESS, SEQUENCE}, + {TK_DLESS, CMD_SUPERIOR}, + {TK_DLESS, AND_OR_MAJOR}, + {TK_DLESS, TK_WHILE}, + {TK_DLESS, TK_UNTIL}, + {TK_DLESS, TK_IF}, + {TK_DLESS, TK_DO}, + {TK_DLESS, TK_ELIF}, + {TK_DLESS, TK_THEN}, + {TK_DLESS, TK_PAREN_CLOSE}, + {TK_DLESS, COMPLETE_CONDITION}, + {TK_DLESS, CONDITION}, + {TK_DLESS, COMPOUND_LIST}, + {TK_DLESS, CMD_SUPERIOR}, + {TK_DLESS, AND_OR_MAJOR}, + {TK_DGREAT, TK_IO_NUMBER}, + {TK_DGREAT, REDIRECT_LIST}, + {TK_DGREAT, CMD_SUFFIX}, + {TK_DGREAT, CMD_PREFIX}, + {TK_DGREAT, CMD_WORD}, + {TK_DGREAT, CMD_NAME}, + {TK_DGREAT, LINEBREAK}, + {TK_DGREAT, TK_BANG}, + {TK_DGREAT, TK_PAREN_OPEN}, + {TK_DGREAT, TK_LBRACE}, + {TK_DGREAT, COMPLETE_COMMANDS}, + {TK_DGREAT, SEPARATOR_OP}, + {TK_DGREAT, NEWLINE_LIST}, + {TK_DGREAT, PIPE_SEMI_SEQUENCE}, + {TK_DGREAT, PIPE_CLOSE_SEQUENCE}, + {TK_DGREAT, SEQUENCE}, + {TK_DGREAT, CMD_SUPERIOR}, + {TK_DGREAT, AND_OR_MAJOR}, + {TK_DGREAT, TK_WHILE}, + {TK_DGREAT, TK_UNTIL}, + {TK_DGREAT, TK_IF}, + {TK_DGREAT, TK_DO}, + {TK_DGREAT, TK_ELIF}, + {TK_DGREAT, TK_THEN}, + {TK_DGREAT, TK_PAREN_CLOSE}, + {TK_DGREAT, COMPLETE_CONDITION}, + {TK_DGREAT, CONDITION}, + {TK_DGREAT, COMPOUND_LIST}, + {TK_DGREAT, CMD_SUPERIOR}, + {TK_DGREAT, AND_OR_MAJOR}, + {TK_LESSAND, TK_IO_NUMBER}, + {TK_LESSAND, REDIRECT_LIST}, + {TK_LESSAND, CMD_SUFFIX}, + {TK_LESSAND, CMD_PREFIX}, + {TK_LESSAND, CMD_WORD}, + {TK_LESSAND, CMD_NAME}, + {TK_LESSAND, LINEBREAK}, + {TK_LESSAND, TK_BANG}, + {TK_LESSAND, TK_PAREN_OPEN}, + {TK_LESSAND, TK_LBRACE}, + {TK_LESSAND, COMPLETE_COMMANDS}, + {TK_LESSAND, SEPARATOR_OP}, + {TK_LESSAND, NEWLINE_LIST}, + {TK_LESSAND, PIPE_SEMI_SEQUENCE}, + {TK_LESSAND, PIPE_CLOSE_SEQUENCE}, + {TK_LESSAND, SEQUENCE}, + {TK_LESSAND, CMD_SUPERIOR}, + {TK_LESSAND, AND_OR_MAJOR}, + {TK_LESSAND, TK_WHILE}, + {TK_LESSAND, TK_UNTIL}, + {TK_LESSAND, TK_IF}, + {TK_LESSAND, TK_DO}, + {TK_LESSAND, TK_ELIF}, + {TK_LESSAND, TK_THEN}, + {TK_LESSAND, TK_PAREN_CLOSE}, + {TK_LESSAND, COMPLETE_CONDITION}, + {TK_LESSAND, CONDITION}, + {TK_LESSAND, COMPOUND_LIST}, + {TK_LESSAND, CMD_SUPERIOR}, + {TK_LESSAND, AND_OR_MAJOR}, + {TK_GREATAND, TK_IO_NUMBER}, + {TK_GREATAND, REDIRECT_LIST}, + {TK_GREATAND, CMD_SUFFIX}, + {TK_GREATAND, CMD_PREFIX}, + {TK_GREATAND, CMD_WORD}, + {TK_GREATAND, CMD_NAME}, + {TK_GREATAND, LINEBREAK}, + {TK_GREATAND, TK_BANG}, + {TK_GREATAND, TK_PAREN_OPEN}, + {TK_GREATAND, TK_LBRACE}, + {TK_GREATAND, COMPLETE_COMMANDS}, + {TK_GREATAND, SEPARATOR_OP}, + {TK_GREATAND, NEWLINE_LIST}, + {TK_GREATAND, PIPE_SEMI_SEQUENCE}, + {TK_GREATAND, PIPE_CLOSE_SEQUENCE}, + {TK_GREATAND, SEQUENCE}, + {TK_GREATAND, CMD_SUPERIOR}, + {TK_GREATAND, AND_OR_MAJOR}, + {TK_GREATAND, TK_WHILE}, + {TK_GREATAND, TK_UNTIL}, + {TK_GREATAND, TK_IF}, + {TK_GREATAND, TK_DO}, + {TK_GREATAND, TK_ELIF}, + {TK_GREATAND, TK_THEN}, + {TK_GREATAND, TK_PAREN_CLOSE}, + {TK_GREATAND, COMPLETE_CONDITION}, + {TK_GREATAND, CONDITION}, + {TK_GREATAND, COMPOUND_LIST}, + {TK_GREATAND, CMD_SUPERIOR}, + {TK_GREATAND, AND_OR_MAJOR}, + {TK_IF, LINEBREAK}, + {TK_IF, TK_BANG}, + {TK_IF, TK_PAREN_OPEN}, + {TK_IF, TK_LBRACE}, + {TK_IF, FUNC_NAME}, + {TK_IF, COMPLETE_COMMANDS}, + {TK_IF, SEPARATOR_OP}, + {TK_IF, NEWLINE_LIST}, + {TK_IF, SEQUENCE}, + {TK_IF, TK_WHILE}, + {TK_IF, FUNC_NAME}, + {TK_IF, TK_UNTIL}, + {TK_IF, TK_IF}, + {TK_IF, TK_DO}, + {TK_IF, TK_ELIF}, + {TK_IF, TK_ELSE}, + {TK_IF, TK_THEN}, + {TK_IF, TK_PAREN_CLOSE}, + {TK_IF, COMPLETE_CONDITION}, + {TK_IF, CONDITION}, + {TK_IF, COMPOUND_LIST}, + {TK_IF, CASE_LIST_NS}, + {TK_IF, AND_OR_MAJOR}, + {TK_THEN, CONDITION}, + {TK_THEN, COMPOUND_LIST}, + {TK_ELSE, COMPOUND_LIST}, + {TK_ELSE, CONDITION}, + {TK_ELSE, COMPLETE_CONDITION}, + {TK_ELIF, COMPOUND_LIST}, + {TK_ELIF, COMPLETE_CONDITION}, + {TK_ELIF, CONDITION}, + {TK_FI, ELSE_PART}, + {TK_FI, COMPOUND_LIST}, + {TK_FI, CMD_SUPERIOR}, + {TK_FI, END_COMMAND}, + {TK_FI, CONDITION}, + {TK_DO, CMD_SUPERIOR}, + {TK_FI, COMPLETE_CONDITION}, + {TK_DO, COMPOUND_LIST}, + {TK_DO, NAME}, + {TK_DO, SEQUENTIAL_SEP}, + {TK_DONE, CMD_SUPERIOR}, + {TK_DONE, COMPOUND_LIST}, + {TK_DONE, END_COMMAND}, + {TK_CASE, LINEBREAK}, + {TK_CASE, TK_BANG}, + {TK_CASE, TK_PAREN_OPEN}, + {TK_CASE, TK_LBRACE}, + {TK_CASE, FUNC_NAME}, + {TK_CASE, COMPLETE_COMMANDS}, + {TK_CASE, TK_DO}, + {TK_CASE, TK_THEN}, + {TK_CASE, TK_PAREN_CLOSE}, + {TK_CASE, TK_WHILE}, + {TK_CASE, FUNC_NAME}, + {TK_CASE, TK_UNTIL}, + {TK_CASE, TK_IF}, + {TK_CASE, TK_ELIF}, + {TK_CASE, TK_ELSE}, + {TK_CASE, COMPLETE_CONDITION}, + {TK_CASE, CONDITION}, + {TK_CASE, CASE_LIST_NS}, + {TK_CASE, COMPOUND_LIST}, + {TK_CASE, NEWLINE_LIST}, + {TK_CASE, SEPARATOR_OP}, + {TK_CASE, AND_OR_MAJOR}, + {TK_CASE, SEQUENCE}, + {TK_IN, TK_WORD}, + {TK_IN, NAME}, + {TK_ESAC, CASE_LIST_NS}, + {TK_ESAC, LINEBREAK}, + {TK_ESAC, TK_IN}, + {TK_WHILE, LINEBREAK}, + {TK_WHILE, TK_PAREN_OPEN}, + {TK_WHILE, TK_LBRACE}, + {TK_WHILE, FUNC_NAME}, + {TK_WHILE, COMPLETE_COMMANDS}, + {TK_WHILE, TK_BANG}, + {TK_WHILE, SEPARATOR_OP}, + {TK_WHILE, NEWLINE_LIST}, + {TK_WHILE, SEQUENCE}, + {TK_WHILE, TK_DO}, + {TK_WHILE, TK_PAREN_CLOSE}, + {TK_WHILE, TK_WHILE}, + {TK_WHILE, FUNC_NAME}, + {TK_WHILE, COMPOUND_LIST}, + {TK_WHILE, CASE_LIST_NS}, + {TK_WHILE, TK_IF}, + {TK_WHILE, TK_ELIF}, + {TK_WHILE, TK_ELSE}, + {TK_WHILE, TK_PAREN_CLOSE}, + {TK_WHILE, TK_THEN}, + {TK_WHILE, COMPLETE_CONDITION}, + {TK_WHILE, CONDITION}, + {TK_WHILE, AND_OR_MAJOR}, + {TK_UNTIL, LINEBREAK}, + {TK_UNTIL, TK_PAREN_OPEN}, + {TK_UNTIL, TK_LBRACE}, + {TK_UNTIL, FUNC_NAME}, + {TK_UNTIL, COMPLETE_COMMANDS}, + {TK_UNTIL, TK_BANG}, + {TK_UNTIL, SEPARATOR_OP}, + {TK_UNTIL, NEWLINE_LIST}, + {TK_UNTIL, SEQUENCE}, + {TK_UNTIL, TK_DO}, + {TK_UNTIL, TK_PAREN_CLOSE}, + {TK_UNTIL, TK_WHILE}, + {TK_UNTIL, FUNC_NAME}, + {TK_UNTIL, COMPOUND_LIST}, + {TK_UNTIL, CASE_LIST_NS}, + {TK_UNTIL, TK_IF}, + {TK_UNTIL, TK_ELIF}, + {TK_UNTIL, TK_ELSE}, + {TK_UNTIL, TK_THEN}, + {TK_UNTIL, TK_PAREN_CLOSE}, + {TK_UNTIL, COMPLETE_CONDITION}, + {TK_UNTIL, CONDITION}, + {TK_UNTIL, AND_OR_MAJOR}, + {FUNC_NAME, LINEBREAK}, + {FUNC_NAME, TK_BANG}, + {FUNC_NAME, TK_PAREN_OPEN}, + {FUNC_NAME, TK_LBRACE}, + {FUNC_NAME, FUNC_NAME}, + {FUNC_NAME, COMPLETE_COMMANDS}, + {FUNC_NAME, SEPARATOR_OP}, + {FUNC_NAME, NEWLINE_LIST}, + {FUNC_NAME, SEQUENCE}, + {FUNC_NAME, TK_WHILE}, + {FUNC_NAME, FUNC_NAME}, + {FUNC_NAME, TK_UNTIL}, + {FUNC_NAME, FUNC_NAME}, + {FUNC_NAME, TK_DO}, + {FUNC_NAME, TK_ELIF}, + {FUNC_NAME, TK_ELSE}, + {FUNC_NAME, TK_THEN}, + {FUNC_NAME, TK_PAREN_CLOSE}, + {FUNC_NAME, COMPLETE_CONDITION}, + {FUNC_NAME, CONDITION}, + {FUNC_NAME, COMPOUND_LIST}, + {FUNC_NAME, CASE_LIST_NS}, + {FUNC_NAME, AND_OR_MAJOR}, + {TK_FOR, LINEBREAK}, + {TK_FOR, TK_BANG}, + {TK_FOR, TK_PAREN_OPEN}, + {TK_FOR, TK_LBRACE}, + {TK_FOR, FUNC_NAME}, + {TK_FOR, COMPLETE_COMMANDS}, + {TK_FOR, SEPARATOR_OP}, + {TK_FOR, NEWLINE_LIST}, + {TK_FOR, SEQUENCE}, + {TK_FOR, TK_DO}, + {TK_FOR, TK_PAREN_CLOSE}, + {TK_FOR, TK_WHILE}, + {TK_FOR, FUNC_NAME}, + {TK_FOR, COMPOUND_LIST}, + {TK_FOR, CASE_LIST_NS}, + {TK_FOR, TK_IF}, + {TK_FOR, TK_ELIF}, + {TK_FOR, TK_THEN}, + {TK_FOR, TK_ELSE}, + {TK_FOR, TK_PAREN_CLOSE}, + {TK_FOR, COMPLETE_CONDITION}, + {TK_FOR, CONDITION}, + {TK_FOR, AND_OR_MAJOR}, + {TK_LBRACE, COMPLETE_COMMANDS}, + {TK_LBRACE, LINEBREAK}, + {TK_LBRACE, TK_BANG}, + {TK_LBRACE, TK_LBRACE}, + {TK_LBRACE, TK_PAREN_OPEN}, + {TK_LBRACE, SEPARATOR_OP}, + {TK_LBRACE, NEWLINE_LIST}, + {TK_LBRACE, SEQUENCE}, + {TK_LBRACE, AND_OR_MAJOR}, + {TK_LBRACE, TK_WHILE}, + {TK_LBRACE, FUNC_NAME}, + {TK_LBRACE, TK_UNTIL}, + {TK_LBRACE, TK_DO}, + {TK_LBRACE, TK_PAREN_CLOSE}, + {TK_LBRACE, TK_IF}, + {TK_LBRACE, TK_ELIF}, + {TK_LBRACE, TK_THEN}, + {TK_LBRACE, TK_ELSE}, + {TK_LBRACE, COMPOUND_LIST}, + {TK_LBRACE, CASE_LIST_NS}, + {TK_LBRACE, COMPLETE_CONDITION}, + {TK_LBRACE, CONDITION}, + {TK_LBRACE, TK_IN}, + {TK_LBRACE, TK_PIPE}, + {TK_RBRACE, TK_SEMI}, + {TK_RBRACE, END_COMMAND}, + {TK_RBRACE, SEPARATOR_OP}, + {TK_RBRACE, WORD}, + {TK_RBRACE, IN}, + {TK_RBRACE, TK_AND_IF}, + {TK_RBRACE, TK_OR_IF}, + {TK_RBRACE, TK_RBRACE}, + {TK_RBRACE, COMPLETE_COMMANDS}, + {TK_RBRACE, CMD_SUPERIOR}, + {TK_RBRACE, PIPE_SEMI_SEQUENCE}, + {TK_RBRACE, PIPE_CLOSE_SEQUENCE}, + {TK_RBRACE, CASE_LIST_NS}, + {TK_RBRACE, PROGRAM}, + {TK_RBRACE, TK_PAREN_OPEN}, + {TK_RBRACE, TK_LBRACE}, + {TK_RBRACE, PATTERN_CASE}, + {TK_RBRACE, PATTERN}, + {TK_RBRACE, COMPOUND_LIST}, + {TK_RBRACE, FUNC_NAME}, + {TK_BANG, LINEBREAK}, + {TK_BANG, TK_PAREN_OPEN}, + {TK_BANG, TK_LBRACE}, + {TK_BANG, COMPLETE_COMMANDS}, + {TK_BANG, SEPARATOR_OP}, + {TK_BANG, NEWLINE_LIST}, + {TK_IN, LINEBREAK}, + {TK_SEMI, NAME}, + {TK_SEMI, IN}, + {TK_SEMI, WORDLIST}, + {TK_SEMI, LIST}, + {TK_SEMI, TERM}, + {TK_SEMI, CMD_NAME}, + {TK_SEMI, PROGRAM}, + {TK_SEMI, FOR_WORDLIST}, + {TK_AMP, LIST}, + {TK_AMP, TERM}, + {TK_PIPE, PATTERN}, + {TK_PIPE, CMD_SUPERIOR}, + {TK_PIPE, PIPE_SEMI_SEQUENCE}, + {TK_PIPE, PIPE_CLOSE_SEQUENCE}, + {PATTERN_CASE, TK_IN}, + {PATTERN_CASE, CASE_LIST_NS}, + {TK_PAREN_OPEN, COMPLETE_COMMANDS}, + {TK_PAREN_OPEN, LINEBREAK}, + {TK_PAREN_OPEN, TK_BANG}, + {TK_PAREN_OPEN, TK_PAREN_OPEN}, + {TK_PAREN_OPEN, SEPARATOR_OP}, + {TK_PAREN_OPEN, NEWLINE_LIST}, + {TK_PAREN_OPEN, SEQUENCE}, + {TK_PAREN_OPEN, FUNC_NAME}, + {TK_PAREN_OPEN, AND_OR_MAJOR}, + {TK_PAREN_OPEN, TK_WHILE}, + {TK_PAREN_OPEN, TK_LBRACE}, + {TK_PAREN_OPEN, FUNC_NAME}, + {TK_PAREN_OPEN, TK_UNTIL}, + {TK_PAREN_OPEN, TK_DO}, + {TK_PAREN_OPEN, TK_PAREN_CLOSE}, + {TK_PAREN_OPEN, TK_IF}, + {TK_PAREN_OPEN, TK_ELIF}, + {TK_PAREN_OPEN, TK_THEN}, + {TK_PAREN_OPEN, TK_ELSE}, + {TK_PAREN_OPEN, COMPOUND_LIST}, + {TK_PAREN_OPEN, CASE_LIST_NS}, + {TK_PAREN_OPEN, COMPLETE_CONDITION}, + {TK_PAREN_OPEN, CONDITION}, + {TK_PAREN_OPEN, TK_IN}, + {TK_PAREN_OPEN, CMD_SUPERIOR}, + {OPEN_FUNC, CMD_SUPERIOR}, + {SEQUENTIAL_SEP, NAME}, + {SEQUENTIAL_SEP, IN}, + {SEQUENTIAL_SEP, WORDLIST}, + {SEQUENTIAL_SEP, FOR_WORDLIST}, + {END_COMMAND, SEQUENCE}, + {END_COMMAND, PIPE_SEMI_SEQUENCE}, + {END_COMMAND, AND_OR_MAJOR}, + {END_COMMAND, TK_WHILE}, + {END_COMMAND, FUNC_NAME}, + {END_COMMAND, TK_UNTIL}, + {END_COMMAND, TK_DO}, + {END_COMMAND, TK_PAREN_CLOSE}, + {END_COMMAND, TK_IF}, + {END_COMMAND, TK_THEN}, + {END_COMMAND, TK_ELIF}, + {END_COMMAND, TK_ELSE}, + {END_COMMAND, LINEBREAK}, + {END_COMMAND, TK_BANG}, + {END_COMMAND, TK_PAREN_OPEN}, + {END_COMMAND, TK_LBRACE}, + {END_COMMAND, COMPLETE_COMMANDS}, + {END_COMMAND, COMPOUND_LIST}, + {END_COMMAND, CASE_LIST_NS}, + {END_COMMAND, COMPLETE_CONDITION}, + {END_COMMAND, CONDITION}, + {SEPARATOR, CMD_SUPERIOR}, + {SEPARATOR, TERM}, + {SEPARATOR, COMPOUND_LIST}, + {SEPARATOR, CASE_LIST_NS}, + {SEPARATOR, PIPE_SEMI_SEQUENCE}, + {SEPARATOR, PIPE_CLOSE_SEQUENCE}, + {SEPARATOR_OP, CMD_SUPERIOR}, + {SEPARATOR_OP, LIST}, + {SEPARATOR_OP, TERM}, + {SEPARATOR_OP, CASE_LIST_NS}, + {SEPARATOR_OP, COMPOUND_LIST}, + {SEPARATOR_OP, PIPE_SEMI_SEQUENCE}, + {SEPARATOR_OP, PIPE_CLOSE_SEQUENCE}, + {LINEBREAK, TK_SEMI}, + {LINEBREAK, END_COMMAND}, + {LINEBREAK, SEPARATOR_OP}, + {LINEBREAK, TK_PAREN_CLOSE}, + {LINEBREAK, WORD}, + {LINEBREAK, IN}, + {LINEBREAK, TK_AND_IF}, + {LINEBREAK, TK_OR_IF}, + {LINEBREAK, TK_PIPE}, + {LINEBREAK, LINEBREAK}, + {LINEBREAK, TK_BANG}, + {LINEBREAK, COMPLETE_COMMANDS}, + {LINEBREAK, CMD_SUPERIOR}, + {LINEBREAK, PIPE_SEMI_SEQUENCE}, + {LINEBREAK, PIPE_CLOSE_SEQUENCE}, + {LINEBREAK, COMPOUND_LIST}, + {LINEBREAK, CASE_LIST_NS}, + {LINEBREAK, PROGRAM}, + {LINEBREAK, TK_PAREN_OPEN}, + {LINEBREAK, TK_LBRACE}, + {TK_PAREN_CLOSE, TK_SEMI}, + {TK_PAREN_CLOSE, END_COMMAND}, + {TK_PAREN_CLOSE, SEPARATOR_OP}, + {TK_PAREN_CLOSE, WORD}, + {TK_PAREN_CLOSE, IN}, + {TK_PAREN_CLOSE, TK_PIPE}, + {TK_PAREN_CLOSE, COMPLETE_COMMANDS}, + {TK_PAREN_CLOSE, CMD_SUPERIOR}, + {TK_PAREN_CLOSE, PIPE_SEMI_SEQUENCE}, + {TK_PAREN_CLOSE, PIPE_CLOSE_SEQUENCE}, + {TK_PAREN_CLOSE, CASE_LIST_NS}, + {TK_PAREN_CLOSE, PROGRAM}, + {TK_PAREN_CLOSE, TK_LBRACE}, + {TK_PAREN_CLOSE, PATTERN_CASE}, + {TK_PAREN_CLOSE, PATTERN}, + {TK_PAREN_CLOSE, COMPOUND_LIST}, + {TK_PAREN_CLOSE, FUNC_NAME}, + {TK_PAREN_CLOSE, OPEN_FUNC}, + {TK_PAREN_CLOSE, SUBSHELL}, + {TK_RBRACE, TK_SEMI}, + {TK_RBRACE, END_COMMAND}, + {TK_RBRACE, SEPARATOR_OP}, + {TK_RBRACE, WORD}, + {TK_RBRACE, IN}, + {TK_RBRACE, TK_PIPE}, + {TK_RBRACE, TK_RBRACE}, + {TK_RBRACE, COMPLETE_COMMANDS}, + {TK_RBRACE, CMD_SUPERIOR}, + {TK_RBRACE, PIPE_SEMI_SEQUENCE}, + {TK_RBRACE, PIPE_CLOSE_SEQUENCE}, + {TK_RBRACE, CASE_LIST_NS}, + {TK_RBRACE, PROGRAM}, + {TK_RBRACE, TK_LBRACE}, + {TK_RBRACE, PATTERN_CASE}, + {TK_RBRACE, PATTERN}, + {TK_RBRACE, COMPOUND_LIST}, + {TK_RBRACE, FUNC_NAME}, + {NEWLINE_LIST, TK_DO}, + {NEWLINE_LIST, CASE_LIST_NS}, + {NEWLINE_LIST, TK_PAREN_CLOSE}, + {NEWLINE_LIST, TK_RBRACE}, + {NEWLINE_LIST, SEQUENTIAL_SEP}, + {NEWLINE_LIST, FOR_WORDLIST}, + {NEWLINE_LIST, TK_IN}, + {NEWLINE_LIST, TK_WHILE}, + {NEWLINE_LIST, LOOP}, + {NEWLINE_LIST, FUNC_NAME}, + {NEWLINE_LIST, TK_UNTIL}, + {NEWLINE_LIST, TK_IF}, + {NEWLINE_LIST, TK_ELIF}, + {NEWLINE_LIST, TK_THEN}, + {NEWLINE_LIST, TK_ELSE}, + {NEWLINE_LIST, CMD_NAME}, + {NEWLINE_LIST, NEWLINE_LIST}, + {NEWLINE_LIST, NAME}, + {NEWLINE_LIST, IN}, + {NEWLINE_LIST, WORDLIST}, + {NEWLINE_LIST, TERM}, + {NEWLINE_LIST, COMPOUND_LIST}, + {NEWLINE_LIST, CASE_LIST_NS}, + {NEWLINE_LIST, COMPLETE_COMMANDS}, + {NEWLINE_LIST, COMPLETE_CONDITION}, + {NEWLINE_LIST, CONDITION}, + {NEWLINE_LIST, LINEBREAK}, + {NEWLINE_LIST, TK_BANG}, + {NEWLINE_LIST, TK_PAREN_OPEN}, + {NEWLINE_LIST, TK_LBRACE}, + {NEWLINE_LIST, PROGRAM}, + {NEWLINE_LIST, SEQUENCE}, + {HERE_END, TK_DLESS}, + {HERE_END, TK_DLESS}, + {HERE_END, TK_DLESSDASH}, + {IO_HERE, TK_IO_NUMBER}, + {IO_HERE, CMD_SUPERIOR}, + {IO_HERE, REDIRECT_LIST}, + {IO_HERE, CMD_SUFFIX}, + {IO_HERE, CMD_PREFIX}, + {IO_HERE, CMD_WORD}, + {IO_HERE, CMD_NAME}, + {IO_HERE, LINEBREAK}, + {IO_HERE, TK_BANG}, + {IO_HERE, TK_PAREN_OPEN}, + {IO_HERE, TK_LBRACE}, + {IO_HERE, COMPLETE_COMMANDS}, + {IO_HERE, SEPARATOR_OP}, + {IO_HERE, NEWLINE_LIST}, + {IO_HERE, PIPE_SEMI_SEQUENCE}, + {IO_HERE, PIPE_CLOSE_SEQUENCE}, + {IO_HERE, SEQUENCE}, + {IO_HERE, CMD_SUPERIOR}, + {IO_HERE, AND_OR_MAJOR}, + {IO_HERE, TK_WHILE}, + {IO_HERE, TK_UNTIL}, + {IO_HERE, TK_IF}, + {IO_HERE, TK_DO}, + {IO_HERE, TK_ELIF}, + {IO_HERE, TK_THEN}, + {IO_HERE, TK_PAREN_CLOSE}, + {IO_HERE, COMPLETE_CONDITION}, + {IO_HERE, CONDITION}, + {IO_HERE, COMPOUND_LIST}, + {FILENAME, TK_LESS}, + {FILENAME, TK_LESSAND}, + {FILENAME, TK_GREAT}, + {FILENAME, TK_GREATAND}, + {FILENAME, TK_DGREAT}, + {FILENAME, TK_LESSGREAT}, + {FILENAME, TK_CLOBBER}, + {IO_FILE, TK_IO_NUMBER}, + {IO_FILE, CMD_SUPERIOR}, + {IO_FILE, REDIRECT_LIST}, + {IO_FILE, CMD_SUFFIX}, + {IO_FILE, CMD_PREFIX}, + {IO_FILE, CMD_WORD}, + {IO_FILE, CMD_NAME}, + {IO_FILE, LINEBREAK}, + {IO_FILE, TK_BANG}, + {IO_FILE, COMPLETE_COMMANDS}, + {IO_FILE, SEPARATOR_OP}, + {IO_FILE, NEWLINE_LIST}, + {IO_FILE, PIPE_SEMI_SEQUENCE}, + {IO_FILE, PIPE_CLOSE_SEQUENCE}, + {IO_FILE, SEQUENCE}, + {IO_FILE, CMD_SUPERIOR}, + {IO_FILE, AND_OR_MAJOR}, + {IO_FILE, TK_WHILE}, + {IO_FILE, TK_UNTIL}, + {IO_FILE, TK_IF}, + {IO_FILE, TK_DO}, + {IO_FILE, TK_ELIF}, + {IO_FILE, TK_THEN}, + {IO_FILE, TK_PAREN_CLOSE}, + {IO_FILE, COMPLETE_CONDITION}, + {IO_FILE, CONDITION}, + {IO_FILE, COMPOUND_LIST}, + {IO_REDIRECT, REDIRECT_LIST}, + {IO_REDIRECT, CMD_SUPERIOR}, + {IO_REDIRECT, CMD_SUFFIX}, + {IO_REDIRECT, CMD_PREFIX}, + {IO_REDIRECT, CMD_WORD}, + {IO_REDIRECT, CMD_NAME}, + {IO_REDIRECT, LINEBREAK}, + {IO_REDIRECT, TK_BANG}, + {IO_REDIRECT, TK_PAREN_OPEN}, + {IO_REDIRECT, TK_LBRACE}, + {IO_REDIRECT, COMPLETE_COMMANDS}, + {IO_REDIRECT, SEPARATOR_OP}, + {IO_REDIRECT, NEWLINE_LIST}, + {IO_REDIRECT, PIPE_SEMI_SEQUENCE}, + {IO_REDIRECT, PIPE_CLOSE_SEQUENCE}, + {IO_REDIRECT, SEQUENCE}, + {IO_REDIRECT, CMD_SUPERIOR}, + {IO_REDIRECT, AND_OR_MAJOR}, + {IO_REDIRECT, TK_WHILE}, + {IO_REDIRECT, TK_UNTIL}, + {IO_REDIRECT, TK_IF}, + {IO_REDIRECT, TK_DO}, + {IO_REDIRECT, TK_ELIF}, + {IO_REDIRECT, TK_THEN}, + {IO_REDIRECT, TK_PAREN_CLOSE}, + {IO_REDIRECT, COMPLETE_CONDITION}, + {IO_REDIRECT, CONDITION}, + {IO_REDIRECT, COMPOUND_LIST}, + {REDIRECT_LIST, COMPOUND_COMMAND}, + {CMD_SUFFIX, CMD_WORD}, + {CMD_SUFFIX, CMD_NAME}, + {CMD_SUFFIX, CMD_SUPERIOR}, + {CMD_SUFFIX, PIPE_SEMI_SEQUENCE}, + {CMD_SUFFIX, PIPE_CLOSE_SEQUENCE}, + {CMD_PREFIX, LINEBREAK}, + {CMD_PREFIX, TK_PAREN_OPEN}, + {CMD_PREFIX, TK_LBRACE}, + {CMD_PREFIX, COMPLETE_COMMANDS}, + {CMD_PREFIX, TK_BANG}, + {CMD_PREFIX, SEPARATOR_OP}, + {CMD_PREFIX, NEWLINE_LIST}, + {CMD_PREFIX, SEQUENCE}, + {CMD_PREFIX, CMD_SUPERIOR}, + {CMD_PREFIX, AND_OR_MAJOR}, + {CMD_PREFIX, TK_WHILE}, + {CMD_PREFIX, TK_UNTIL}, + {CMD_PREFIX, TK_IF}, + {CMD_PREFIX, TK_DO}, + {CMD_PREFIX, TK_ELIF}, + {CMD_PREFIX, TK_THEN}, + {CMD_PREFIX, TK_PAREN_CLOSE}, + {CMD_PREFIX, COMPLETE_CONDITION}, + {CMD_PREFIX, CONDITION}, + {CMD_PREFIX, COMPOUND_LIST}, + {CMD_WORD, CMD_PREFIX}, + {CMD_NAME, COMPLETE_COMMANDS}, + {CMD_NAME, LINEBREAK}, + {CMD_NAME, TK_PAREN_OPEN}, + {CMD_NAME, TK_LBRACE}, + {CMD_NAME, TK_BANG}, + {CMD_NAME, SEPARATOR_OP}, + {CMD_NAME, NEWLINE_LIST}, + {CMD_NAME, SEQUENCE}, + {CMD_NAME, CMD_SUPERIOR}, + {CMD_NAME, AND_OR_MAJOR}, + {CMD_NAME, CONDITION}, + {CMD_NAME, COMPOUND_LIST}, + {CMD_NAME, AND_OR_MAJOR}, + {CMD_NAME, TK_WHILE}, + {CMD_NAME, FUNC_NAME}, + {CMD_NAME, TK_UNTIL}, + {CMD_NAME, TK_DO}, + {CMD_NAME, TK_PAREN_CLOSE}, + {CMD_NAME, TK_IF}, + {CMD_NAME, TK_ELIF}, + {CMD_NAME, TK_THEN}, + {CMD_NAME, TK_ELSE}, + {CMD_NAME, COMPOUND_LIST}, + {CMD_NAME, CASE_LIST_NS}, + {CMD_NAME, COMPLETE_CONDITION}, + {CMD_NAME, CONDITION}, + {CMD_SUPERIOR, TK_WHILE}, + {CMD_SUPERIOR, FUNC_NAME}, + {CMD_SUPERIOR, TK_UNTIL}, + {CMD_SUPERIOR, TK_DO}, + {CMD_SUPERIOR, TK_PAREN_CLOSE}, + {CMD_SUPERIOR, TK_IF}, + {CMD_SUPERIOR, TK_ELIF}, + {CMD_SUPERIOR, TK_THEN}, + {CMD_SUPERIOR, TK_ELSE}, + {CMD_SUPERIOR, COMPOUND_LIST}, + {CMD_SUPERIOR, CASE_LIST_NS}, + {CMD_SUPERIOR, COMPLETE_CONDITION}, + {CMD_SUPERIOR, CONDITION}, + {CMD_SUPERIOR, LINEBREAK}, + {CMD_SUPERIOR, TK_PAREN_OPEN}, + {CMD_SUPERIOR, TK_LBRACE}, + {CMD_SUPERIOR, COMPLETE_COMMANDS}, + {CMD_SUPERIOR, TK_BANG}, + {CMD_SUPERIOR, SEPARATOR_OP}, + {CMD_SUPERIOR, NEWLINE_LIST}, + {CMD_SUPERIOR, TK_PIPE}, + {CMD_SUPERIOR, SEQUENCE}, + {CMD_SUPERIOR, AND_OR_MAJOR}, + {CLOSE_FUNC, CMD_SUPERIOR}, + {CLOSE_FUNC, OPEN_FUNC}, + {SIMPLE_COMMAND, TK_WHILE}, + {SIMPLE_COMMAND, TK_UNTIL}, + {SIMPLE_COMMAND, TK_DO}, + {SIMPLE_COMMAND, TK_PAREN_CLOSE}, + {SIMPLE_COMMAND, TK_IF}, + {SIMPLE_COMMAND, TK_ELIF}, + {SIMPLE_COMMAND, TK_THEN}, + {SIMPLE_COMMAND, TK_ELSE}, + {SIMPLE_COMMAND, COMPOUND_LIST}, + {SIMPLE_COMMAND, CASE_LIST_NS}, + {SIMPLE_COMMAND, COMPLETE_CONDITION}, + {SIMPLE_COMMAND, CONDITION}, + {SIMPLE_COMMAND, LINEBREAK}, + {SIMPLE_COMMAND, TK_PAREN_OPEN}, + {SIMPLE_COMMAND, TK_LBRACE}, + {SIMPLE_COMMAND, COMPLETE_COMMANDS}, + {SIMPLE_COMMAND, TK_BANG}, + {SIMPLE_COMMAND, SEPARATOR_OP}, + {SIMPLE_COMMAND, NEWLINE_LIST}, + {SIMPLE_COMMAND, SEQUENCE}, + {SIMPLE_COMMAND, AND_OR_MAJOR}, + {DO_GROUP, CMD_SUPERIOR}, + {DO_GROUP, COMPOUND_LIST}, + {DO_GROUP, NAME}, + {DO_GROUP, SEQUENTIAL_SEP}, + {LOOP, TK_WHILE}, + {LOOP, FUNC_NAME}, + {LOOP, TK_UNTIL}, + {CONDITION, LINEBREAK}, + {CONDITION, TK_PAREN_OPEN}, + {CONDITION, TK_LBRACE}, + {CONDITION, COMPLETE_COMMANDS}, + {CONDITION, COMPOUND_LIST}, + {CONDITION, CASE_LIST_NS}, + {CONDITION, COMPLETE_CONDITION}, + {CONDITION, SEQUENCE}, + {COMPLETE_CONDITION, LINEBREAK}, + {COMPLETE_CONDITION, TK_PAREN_OPEN}, + {COMPLETE_CONDITION, TK_LBRACE}, + {COMPLETE_CONDITION, COMPLETE_COMMANDS}, + {COMPLETE_CONDITION, COMPLETE_CONDITION}, + {COMPLETE_CONDITION, SEQUENCE}, + {COMPLETE_CONDITION, TK_WHILE}, + {COMPLETE_CONDITION, TK_UNTIL}, + {COMPLETE_CONDITION, TK_DO}, + {COMPLETE_CONDITION, TK_IF}, + {COMPLETE_CONDITION, TK_ELIF}, + {COMPLETE_CONDITION, TK_THEN}, + {COMPLETE_CONDITION, TK_ELSE}, + {COMPLETE_CONDITION, COMPOUND_LIST}, + {COMPLETE_CONDITION, CASE_LIST_NS}, + {COMPLETE_CONDITION, TK_BANG}, + {COMPLETE_CONDITION, SEPARATOR_OP}, + {COMPLETE_CONDITION, NEWLINE_LIST}, + {COMPLETE_CONDITION, AND_OR_MAJOR}, + {COMPLETE_CONDITION, CASE_LIST_NS}, + {COMPLETE_CONDITION, FUNC_NAME}, + {FNAME, LINEBREAK}, + {FNAME, TK_PAREN_OPEN}, + {FNAME, TK_LBRACE}, + {FNAME, COMPLETE_COMMANDS}, + {FNAME, TK_BANG}, + {FNAME, SEPARATOR_OP}, + {FNAME, NEWLINE_LIST}, + {FNAME, SEQUENCE}, + {FUNCTION_BODY, FUNC}, + {FUNCTION_DEFINITION, LINEBREAK}, + {FUNCTION_DEFINITION, TK_PAREN_OPEN}, + {FUNCTION_DEFINITION, TK_LBRACE}, + {FUNCTION_DEFINITION, FUNC_NAME}, + {FUNCTION_DEFINITION, COMPLETE_COMMANDS}, + {FUNCTION_DEFINITION, TK_BANG}, + {FUNCTION_DEFINITION, SEPARATOR_OP}, + {FUNCTION_DEFINITION, NEWLINE_LIST}, + {FUNCTION_DEFINITION, SEQUENCE}, + {UNTIL_CLAUSE, LINEBREAK}, + {UNTIL_CLAUSE, TK_PAREN_OPEN}, + {UNTIL_CLAUSE, TK_LBRACE}, + {UNTIL_CLAUSE, FUNC_NAME}, + {UNTIL_CLAUSE, COMPLETE_COMMANDS}, + {UNTIL_CLAUSE, TK_BANG}, + {UNTIL_CLAUSE, SEPARATOR_OP}, + {UNTIL_CLAUSE, NEWLINE_LIST}, + {UNTIL_CLAUSE, SEQUENCE}, + {UNTIL_CLAUSE, TK_DO}, + {UNTIL_CLAUSE, TK_PAREN_CLOSE}, + {UNTIL_CLAUSE, TK_WHILE}, + {UNTIL_CLAUSE, FUNC_NAME}, + {UNTIL_CLAUSE, TK_UNTIL}, + {UNTIL_CLAUSE, TK_IF}, + {UNTIL_CLAUSE, TK_ELIF}, + {UNTIL_CLAUSE, TK_THEN}, + {UNTIL_CLAUSE, TK_ELSE}, + {UNTIL_CLAUSE, COMPOUND_LIST}, + {UNTIL_CLAUSE, CASE_LIST_NS}, + {UNTIL_CLAUSE, COMPLETE_CONDITION}, + {UNTIL_CLAUSE, CONDITION}, + {UNTIL_CLAUSE, AND_OR_MAJOR}, + {WHILE_CLAUSE, LINEBREAK}, + {WHILE_CLAUSE, COMPLETE_COMMANDS}, + {WHILE_CLAUSE, TK_BANG}, + {WHILE_CLAUSE, SEPARATOR_OP}, + {WHILE_CLAUSE, NEWLINE_LIST}, + {WHILE_CLAUSE, SEQUENCE}, + {WHILE_CLAUSE, TK_DO}, + {WHILE_CLAUSE, TK_PAREN_OPEN}, + {WHILE_CLAUSE, TK_PAREN_CLOSE}, + {WHILE_CLAUSE, TK_WHILE}, + {WHILE_CLAUSE, TK_LBRACE}, + {WHILE_CLAUSE, FUNC_NAME}, + {WHILE_CLAUSE, TK_UNTIL}, + {WHILE_CLAUSE, TK_IF}, + {WHILE_CLAUSE, TK_ELIF}, + {WHILE_CLAUSE, TK_THEN}, + {WHILE_CLAUSE, TK_ELSE}, + {WHILE_CLAUSE, COMPOUND_LIST}, + {WHILE_CLAUSE, CASE_LIST_NS}, + {WHILE_CLAUSE, COMPLETE_CONDITION}, + {WHILE_CLAUSE, CONDITION}, + {WHILE_CLAUSE, AND_OR_MAJOR}, + {IF_CLAUSE, LINEBREAK}, + {IF_CLAUSE, TK_BANG}, + {IF_CLAUSE, TK_PAREN_OPEN}, + {IF_CLAUSE, TK_LBRACE}, + {IF_CLAUSE, FUNC_NAME}, + {IF_CLAUSE, COMPLETE_COMMANDS}, + {IF_CLAUSE, SEPARATOR_OP}, + {IF_CLAUSE, NEWLINE_LIST}, + {IF_CLAUSE, SEQUENCE}, + {IF_CLAUSE, TK_DO}, + {IF_CLAUSE, TK_PAREN_CLOSE}, + {IF_CLAUSE, TK_WHILE}, + {IF_CLAUSE, FUNC_NAME}, + {IF_CLAUSE, TK_UNTIL}, + {IF_CLAUSE, TK_IF}, + {IF_CLAUSE, TK_ELIF}, + {IF_CLAUSE, TK_THEN}, + {IF_CLAUSE, TK_ELSE}, + {IF_CLAUSE, COMPOUND_LIST}, + {IF_CLAUSE, CASE_LIST_NS}, + {IF_CLAUSE, COMPLETE_COMMAND}, + {IF_CLAUSE, COMPLETE_CONDITION}, + {IF_CLAUSE, CONDITION}, + {IF_CLAUSE, AND_OR_MAJOR}, + {BRACE_CLAUSE, LINEBREAK}, + {BRACE_CLAUSE, TK_PAREN_OPEN}, + {BRACE_CLAUSE, TK_LBRACE}, + {BRACE_CLAUSE, FUNC_NAME}, + {BRACE_CLAUSE, COMPLETE_COMMANDS}, + {BRACE_CLAUSE, TK_BANG}, + {BRACE_CLAUSE, SEPARATOR_OP}, + {BRACE_CLAUSE, NEWLINE_LIST}, + {BRACE_CLAUSE, SEQUENCE}, + {BRACE_CLAUSE, TK_DO}, + {BRACE_CLAUSE, TK_PAREN_CLOSE}, + {BRACE_CLAUSE, TK_WHILE}, + {BRACE_CLAUSE, FUNC_NAME}, + {BRACE_CLAUSE, TK_UNTIL}, + {BRACE_CLAUSE, TK_IF}, + {BRACE_CLAUSE, TK_ELIF}, + {BRACE_CLAUSE, TK_THEN}, + {BRACE_CLAUSE, TK_ELSE}, + {BRACE_CLAUSE, COMPOUND_LIST}, + {BRACE_CLAUSE, CASE_LIST_NS}, + {BRACE_CLAUSE, COMPLETE_COMMAND}, + {BRACE_CLAUSE, COMPLETE_CONDITION}, + {BRACE_CLAUSE, CONDITION}, + {BRACE_CLAUSE, AND_OR_MAJOR}, + {PATTERN, PATTERN_CASE}, + {PATTERN, CASE_LIST}, + {PATTERN, TK_IN}, + {CASE_LIST_NS, LINEBREAK}, + {CASE_LIST_NS, TK_IN}, + {CASE_CLAUSE, LINEBREAK}, + {CASE_CLAUSE, TK_BANG}, + {CASE_CLAUSE, TK_PAREN_OPEN}, + {CASE_CLAUSE, TK_LBRACE}, + {CASE_CLAUSE, FUNC_NAME}, + {CASE_CLAUSE, COMPLETE_COMMANDS}, + {CASE_CLAUSE, SEPARATOR_OP}, + {CASE_CLAUSE, NEWLINE_LIST}, + {CASE_CLAUSE, SEQUENCE}, + {CASE_CLAUSE, TK_PAREN_CLOSE}, + {CASE_CLAUSE, CASE_LIST_NS}, + {CASE_CLAUSE, TK_DO}, + {CASE_CLAUSE, TK_WHILE}, + {CASE_CLAUSE, FUNC_NAME}, + {CASE_CLAUSE, TK_UNTIL}, + {CASE_CLAUSE, TK_IF}, + {CASE_CLAUSE, TK_ELIF}, + {CASE_CLAUSE, TK_THEN}, + {CASE_CLAUSE, TK_ELSE}, + {CASE_CLAUSE, COMPOUND_LIST}, + {CASE_CLAUSE, CASE_LIST_NS}, + {CASE_CLAUSE, COMPLETE_CONDITION}, + {CASE_CLAUSE, CONDITION}, + {CASE_CLAUSE, AND_OR_MAJOR}, + {WORDLIST, IN}, + {IN, LINEBREAK}, + {NAME, TK_FOR}, + {FOR_WORDLIST, NAME}, + {FOR_CLAUSE, LINEBREAK}, + {FOR_CLAUSE, TK_BANG}, + {FOR_CLAUSE, TK_PAREN_OPEN}, + {FOR_CLAUSE, TK_LBRACE}, + {FOR_CLAUSE, FUNC_NAME}, + {FOR_CLAUSE, COMPLETE_COMMANDS}, + {FOR_CLAUSE, SEPARATOR_OP}, + {FOR_CLAUSE, NEWLINE_LIST}, + {FOR_CLAUSE, SEQUENCE}, + {FOR_CLAUSE, TK_DO}, + {FOR_CLAUSE, TK_PAREN_CLOSE}, + {FOR_CLAUSE, TK_WHILE}, + {FOR_CLAUSE, FUNC_NAME}, + {FOR_CLAUSE, TK_UNTIL}, + {FOR_CLAUSE, TK_IF}, + {FOR_CLAUSE, TK_ELIF}, + {FOR_CLAUSE, TK_THEN}, + {FOR_CLAUSE, TK_ELSE}, + {FOR_CLAUSE, COMPOUND_LIST}, + {FOR_CLAUSE, CASE_LIST_NS}, + {FOR_CLAUSE, COMPLETE_CONDITION}, + {FOR_CLAUSE, CONDITION}, + {FOR_CLAUSE, AND_OR_MAJOR}, + {COMPOUND_LIST, TK_DO}, + {COMPOUND_LIST, TK_PAREN_CLOSE}, + {COMPOUND_LIST, TK_LBRACE}, + {COMPOUND_LIST, TK_WHILE}, + {COMPOUND_LIST, FUNC_NAME}, + {COMPOUND_LIST, TK_UNTIL}, + {COMPOUND_LIST, TK_ELIF}, + {COMPOUND_LIST, TK_ELSE}, + {COMPOUND_LIST, TK_IF}, + {COMPOUND_LIST, TK_THEN}, + {COMPOUND_LIST, TK_ELSE}, + {COMPOUND_LIST, COMPOUND_LIST}, + {COMPOUND_LIST, COMPLETE_CONDITION}, + {COMPOUND_LIST, CONDITION}, + {CLOSE_LIST, PATTERN}, + {CLOSE_LIST, FUNC_NAME}, + {SUBSHELL, LINEBREAK}, + {SUBSHELL, COMPLETE_COMMANDS}, + {SUBSHELL, TK_BANG}, + {SUBSHELL, SEPARATOR_OP}, + {SUBSHELL, NEWLINE_LIST}, + {SUBSHELL, SEQUENCE}, + {SUBSHELL, TK_LBRACE}, + {SUBSHELL, TK_PAREN_OPEN}, + {SUBSHELL, SEPARATOR_OP}, + {SUBSHELL, NEWLINE_LIST}, + {SUBSHELL, TK_DO}, + {SUBSHELL, TK_PAREN_CLOSE}, + {SUBSHELL, TK_WHILE}, + {SUBSHELL, FUNC_NAME}, + {SUBSHELL, TK_UNTIL}, + {SUBSHELL, TK_IF}, + {SUBSHELL, TK_ELIF}, + {SUBSHELL, TK_THEN}, + {SUBSHELL, TK_ELSE}, + {SUBSHELL, COMPOUND_LIST}, + {SUBSHELL, CASE_LIST_NS}, + {SUBSHELL, COMPLETE_CONDITION}, + {SUBSHELL, CONDITION}, + {SUBSHELL, AND_OR_MAJOR}, + {COMPOUND_COMMAND, LINEBREAK}, + {COMPOUND_COMMAND, TK_PAREN_OPEN}, + {COMPOUND_COMMAND, TK_LBRACE}, + {COMPOUND_COMMAND, COMPLETE_COMMANDS}, + {COMPOUND_COMMAND, TK_BANG}, + {COMPOUND_COMMAND, SEPARATOR_OP}, + {COMPOUND_COMMAND, NEWLINE_LIST}, + {COMPOUND_COMMAND, SEQUENCE}, + {COMPOUND_COMMAND, FUNC}, + {COMPOUND_COMMAND, TK_DO}, + {COMPOUND_COMMAND, TK_PAREN_CLOSE}, + {COMPOUND_COMMAND, TK_WHILE}, + {COMPOUND_COMMAND, FUNC_NAME}, + {COMPOUND_COMMAND, TK_UNTIL}, + {COMPOUND_COMMAND, TK_IF}, + {COMPOUND_COMMAND, TK_ELIF}, + {COMPOUND_COMMAND, TK_THEN}, + {COMPOUND_COMMAND, TK_ELSE}, + {COMPOUND_COMMAND, COMPOUND_LIST}, + {COMPOUND_COMMAND, CASE_LIST_NS}, + {COMPOUND_COMMAND, COMPLETE_CONDITION}, + {COMPOUND_COMMAND, CONDITION}, + {COMPOUND_COMMAND, AND_OR_MAJOR}, + {COMMAND, TK_WHILE}, + {COMMAND, TK_UNTIL}, + {COMMAND, LINEBREAK}, + {COMMAND, TK_BANG}, + {COMMAND, TK_PAREN_OPEN}, + {COMMAND, TK_LBRACE}, + {COMMAND, COMPLETE_COMMANDS}, + {COMMAND, TK_DO}, + {COMMAND, TK_PAREN_CLOSE}, + {COMMAND, TK_IF}, + {COMMAND, TK_ELIF}, + {COMMAND, TK_THEN}, + {COMMAND, TK_ELSE}, + {COMMAND, COMPOUND_LIST}, + {COMMAND, CASE_LIST_NS}, + {COMMAND, COMPLETE_CONDITION}, + {COMMAND, CONDITION}, + {COMMAND, SEPARATOR_OP}, + {COMMAND, NEWLINE_LIST}, + {COMMAND, SEQUENCE}, + {COMMAND, AND_OR_MAJOR}, + {AND_OR_MINOR, SEQUENCE}, + {AND_OR_MINOR, LINEBREAK}, + {AND_OR_MINOR, TK_BANG}, + {AND_OR_MINOR, TK_PAREN_OPEN}, + {AND_OR_MINOR, TK_LBRACE}, + {AND_OR_MINOR, COMPLETE_COMMANDS}, + {AND_OR_MINOR, COMPOUND_LIST}, + {AND_OR_MINOR, AND_OR_MAJOR}, + {AND_OR_MINOR, COMPLETE_CONDITION}, + {AND_OR_MINOR, TK_DO}, + {AND_OR_MINOR, TK_PAREN_CLOSE}, + {PIPE_SEQUENCE, TK_WHILE}, + {PIPE_SEQUENCE, FUNC_NAME}, + {PIPE_SEQUENCE, TK_UNTIL}, + {PIPE_SEQUENCE, TK_DO}, + {PIPE_SEQUENCE, TK_PAREN_CLOSE}, + {PIPE_SEQUENCE, TK_IF}, + {PIPE_SEQUENCE, TK_ELIF}, + {PIPE_SEQUENCE, TK_THEN}, + {PIPE_SEQUENCE, TK_ELSE}, + {PIPE_SEQUENCE, COMPOUND_LIST}, + {PIPE_SEQUENCE, CASE_LIST_NS}, + {PIPE_SEQUENCE, COMPLETE_CONDITION}, + {PIPE_SEQUENCE, CONDITION}, + {PIPE_SEQUENCE, LINEBREAK}, + {PIPE_SEQUENCE, TK_BANG}, + {PIPE_SEQUENCE, TK_PAREN_OPEN}, + {PIPE_SEQUENCE, TK_LBRACE}, + {PIPE_SEQUENCE, COMPLETE_COMMANDS}, + {PIPE_SEQUENCE, SEPARATOR_OP}, + {PIPE_SEQUENCE, NEWLINE_LIST}, + {PIPE_SEQUENCE, AND_OR_MAJOR}, + {TK_BANG, TK_WHILE}, + {TK_BANG, TK_UNTIL}, + {TK_BANG, TK_DO}, + {TK_BANG, TK_PAREN_CLOSE}, + {TK_BANG, TK_IF}, + {TK_BANG, TK_ELIF}, + {TK_BANG, TK_THEN}, + {TK_BANG, TK_ELSE}, + {TK_BANG, COMPOUND_LIST}, + {TK_BANG, CASE_LIST_NS}, + {TK_BANG, COMPLETE_CONDITION}, + {TK_BANG, CONDITION}, + {TK_BANG, LINEBREAK}, + {TK_BANG, TK_PAREN_OPEN}, + {TK_BANG, TK_LBRACE}, + {TK_BANG, COMPLETE_COMMANDS}, + {TK_BANG, SEPARATOR_OP}, + {TK_BANG, NEWLINE_LIST}, + {TK_BANG, AND_OR_MAJOR}, + {PIPE_SEMI_SEQUENCE, TK_WHILE}, + {PIPE_SEMI_SEQUENCE, TK_UNTIL}, + {PIPE_SEMI_SEQUENCE, TK_DO}, + {PIPE_SEMI_SEQUENCE, TK_PAREN_CLOSE}, + {PIPE_SEMI_SEQUENCE, TK_IF}, + {PIPE_SEMI_SEQUENCE, TK_ELIF}, + {PIPE_SEMI_SEQUENCE, TK_THEN}, + {PIPE_SEMI_SEQUENCE, TK_ELSE}, + {PIPE_SEMI_SEQUENCE, COMPOUND_LIST}, + {PIPE_SEMI_SEQUENCE, CASE_LIST_NS}, + {PIPE_SEMI_SEQUENCE, COMPLETE_CONDITION}, + {PIPE_SEMI_SEQUENCE, CONDITION}, + {PIPE_SEMI_SEQUENCE, LINEBREAK}, + {PIPE_SEMI_SEQUENCE, TK_BANG}, + {PIPE_SEMI_SEQUENCE, TK_PAREN_OPEN}, + {PIPE_SEMI_SEQUENCE, TK_LBRACE}, + {PIPE_SEMI_SEQUENCE, COMPLETE_COMMANDS}, + {PIPE_SEMI_SEQUENCE, SEPARATOR_OP}, + {PIPE_SEMI_SEQUENCE, NEWLINE_LIST}, + {PIPE_SEMI_SEQUENCE, AND_OR_MAJOR}, + {PIPE_SEMI_SEQUENCE, SEQUENCE}, + {PIPE_CLOSE_SEQUENCE, TK_WHILE}, + {PIPE_CLOSE_SEQUENCE, TK_UNTIL}, + {PIPE_CLOSE_SEQUENCE, TK_DO}, + {PIPE_CLOSE_SEQUENCE, TK_PAREN_CLOSE}, + {PIPE_CLOSE_SEQUENCE, TK_IF}, + {PIPE_CLOSE_SEQUENCE, TK_ELIF}, + {PIPE_CLOSE_SEQUENCE, TK_THEN}, + {PIPE_CLOSE_SEQUENCE, TK_ELSE}, + {PIPE_CLOSE_SEQUENCE, COMPOUND_LIST}, + {PIPE_CLOSE_SEQUENCE, CASE_LIST_NS}, + {PIPE_CLOSE_SEQUENCE, COMPLETE_CONDITION}, + {PIPE_CLOSE_SEQUENCE, CONDITION}, + {PIPE_CLOSE_SEQUENCE, LINEBREAK}, + {PIPE_CLOSE_SEQUENCE, TK_BANG}, + {PIPE_CLOSE_SEQUENCE, TK_PAREN_OPEN}, + {PIPE_CLOSE_SEQUENCE, TK_LBRACE}, + {PIPE_CLOSE_SEQUENCE, COMPLETE_COMMANDS}, + {PIPE_CLOSE_SEQUENCE, SEPARATOR_OP}, + {PIPE_CLOSE_SEQUENCE, NEWLINE_LIST}, + {PIPE_CLOSE_SEQUENCE, AND_OR_MAJOR}, + {PIPE_CLOSE_SEQUENCE, SEQUENCE}, + {SEQUENCE, PIPE_SEMI_SEQUENCE}, + {SEQUENCE, PIPE_CLOSE_SEQUENCE}, + {SEQUENCE, TK_WHILE}, + {SEQUENCE, TK_UNTIL}, + {SEQUENCE, TK_DO}, + {SEQUENCE, TK_PAREN_CLOSE}, + {SEQUENCE, TK_IF}, + {SEQUENCE, TK_ELIF}, + {SEQUENCE, TK_THEN}, + {SEQUENCE, TK_ELSE}, + {SEQUENCE, COMPOUND_LIST}, + {SEQUENCE, CASE_LIST_NS}, + {SEQUENCE, COMPLETE_CONDITION}, + {SEQUENCE, CONDITION}, + {SEQUENCE, LINEBREAK}, + {SEQUENCE, TK_PAREN_OPEN}, + {SEQUENCE, TK_LBRACE}, + {SEQUENCE, COMPLETE_COMMANDS}, + {SEQUENCE, TK_BANG}, + {SEQUENCE, SEPARATOR_OP}, + {SEQUENCE, NEWLINE_LIST}, + {SEQUENCE, AND_OR_MAJOR}, + {SEQUENCE, SEQUENCE}, + {PIPELINE, TK_WHILE}, + {PIPELINE, TK_UNTIL}, + {PIPELINE, TK_DO}, + {PIPELINE, TK_PAREN_CLOSE}, + {PIPELINE, TK_IF}, + {PIPELINE, TK_ELIF}, + {PIPELINE, TK_THEN}, + {PIPELINE, TK_ELSE}, + {PIPELINE, COMPOUND_LIST}, + {PIPELINE, CASE_LIST_NS}, + {PIPELINE, COMPLETE_CONDITION}, + {PIPELINE, CONDITION}, + {PIPELINE, LINEBREAK}, + {PIPELINE, TK_BANG}, + {PIPELINE, TK_PAREN_OPEN}, + {PIPELINE, TK_LBRACE}, + {PIPELINE, COMPLETE_COMMANDS}, + {PIPELINE, SEPARATOR_OP}, + {PIPELINE, SEPARATOR_OP}, + {PIPELINE, NEWLINE_LIST}, + {PIPELINE, AND_OR_MAJOR}, + {AND_OR_MAJOR, LINEBREAK}, + {AND_OR_MAJOR, TK_BANG}, + {AND_OR_MAJOR, TK_PAREN_OPEN}, + {AND_OR_MAJOR, TK_LBRACE}, + {AND_OR_MAJOR, COMPOUND_LIST}, + {AND_OR_MAJOR, COMPLETE_COMMANDS}, + {AND_OR_MAJOR, AND_OR_MAJOR}, + {AND_OR_MAJOR, AND_OR_MAJOR}, + {AND_OR, TK_DO}, + {AND_OR, TK_PAREN_CLOSE}, + {AND_OR, TK_WHILE}, + {AND_OR, TK_UNTIL}, + {AND_OR, TK_IF}, + {AND_OR, TK_ELIF}, + {AND_OR, TK_THEN}, + {AND_OR, TK_ELSE}, + {AND_OR, COMPOUND_LIST}, + {AND_OR, CASE_LIST_NS}, + {AND_OR, COMPLETE_CONDITION}, + {AND_OR, CONDITION}, + {AND_OR, LINEBREAK}, + {AND_OR, TK_BANG}, + {AND_OR, TK_PAREN_OPEN}, + {AND_OR, TK_LBRACE}, + {AND_OR, COMPLETE_COMMANDS}, + {AND_OR, SEPARATOR_OP}, + {AND_OR, SEPARATOR_OP}, + {AND_OR, NEWLINE_LIST}, + {LIST, LINEBREAK}, + {LIST, COMPLETE_COMMANDS}, + {LIST, NEWLINE_LIST}, + {COMPLETE_COMMAND, LINEBREAK}, + {COMPLETE_COMMAND, COMPLETE_COMMANDS}, + {COMPLETE_COMMAND, NEWLINE_LIST}, + {COMPLETE_COMMANDS, COMPLETE_COMMANDS}, + {PROGRAM, TERMINUS}, + {0, 0}, +}; + +int eval_sym(t_list **stack, t_sym new_sym) +{ + t_sym *head; + int i; + + if (!*stack) + return (1); + head = (*stack)->content; + i = 0; + DG("eval %s && %s", read_state(*head), read_state(new_sym)); + while (g_stackmatch[i].top) + { + if (new_sym == g_stackmatch[i].top && *head == g_stackmatch[i].under) + return (0); + i++; + } + return (1); +} diff --git a/42sh/src/parser/ft_parse.c b/42sh/src/parser/ft_parse.c new file mode 100644 index 00000000..596669d4 --- /dev/null +++ b/42sh/src/parser/ft_parse.c @@ -0,0 +1,59 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_parse.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ariard +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/11 16:17:38 by ariard #+# #+# */ +/* Updated: 2017/03/29 15:43:05 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static void insert_linebreak(t_list **lst) +{ + t_token *token; + + token = (*lst)->content; + token->type = LINEBREAK; +} + +static int end_instruction(t_list **stack) +{ + t_sym *head; + + head = (*stack)->content; + if (*head == CMD_SUPERIOR || *head == PIPE_SEMI_SEQUENCE + || *head == COMPLETE_COMMANDS || *head == END_COMMAND) + return (1); + return (0); +} + +int ft_parse(t_btree **ast, t_list **token, t_parser *parser) +{ + t_sym *head; + + if (pop_heredoc(token)) + return (0); + while (parser && token && *token) + { + produce_sym(&parser->stack, parser->new_sym, token); + if (parser->new_sym && eval_sym(&parser->stack, *parser->new_sym)) + return ((parser->state = ERROR)); + if (aggregate_sym(&parser->stack, parser->new_sym, &parser->state)) + return (0); + push_stack(&parser->stack, *parser->new_sym); + if (*(head = (parser->stack)->content) == PROGRAM) + parser->state = SUCCESS; + else + parser->state = UNDEFINED; + build_tree(ast, token, parser); + if ((end_instruction(&parser->stack) && !(*token)->next)) + insert_linebreak(token); + else + ft_lst_delif(token, (*token)->content, &ft_addrcmp, &token_free); + } + return (0); +} diff --git a/42sh/src/parser/heredoc_parser.c b/42sh/src/parser/heredoc_parser.c new file mode 100644 index 00000000..d6dd9a05 --- /dev/null +++ b/42sh/src/parser/heredoc_parser.c @@ -0,0 +1,51 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* heredoc_parser.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ariard +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/08 16:21:05 by ariard #+# #+# */ +/* Updated: 2017/03/28 23:21:22 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static char *join_heredoc_data(char *old_data, char *token_data) +{ + char *del; + char *new; + + del = old_data; + new = ft_str3join(old_data, token_data, "\n"); + ft_strdel(&del); + return (new); +} + +int pop_heredoc(t_list **lst) +{ + t_token *token; + t_list **head; + t_redir *redir; + + if (!lst || !*lst) + return (0); + token = (*lst)->content; + if ((token->type == HEREDOCDATA || token->type == TK_NEWLINE) + && data_singleton()->parser.heredoc_queue != NULL) + { + if (!(head = &data_singleton()->parser.heredoc_queue)) + return (0); + redir = *(t_redir**)(*head)->content; + if (ft_strcmp((char *)token->data, redir->word) == 0) + ft_lst_delif(head, (t_redir**)(*head)->content, + ft_addrcmp, ft_lst_cfree); + else + redir->heredoc_data = join_heredoc_data(redir->heredoc_data, + (char*)token->data); + ft_lstdel(lst, &token_free); + return (1); + } + return (0); +} diff --git a/42sh/src/parser/parser_destroy.c b/42sh/src/parser/parser_destroy.c new file mode 100644 index 00000000..97c3abe0 --- /dev/null +++ b/42sh/src/parser/parser_destroy.c @@ -0,0 +1,23 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* parser_destroy.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ariard +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/16 19:30:17 by ariard #+# #+# */ +/* Updated: 2017/03/29 15:42:05 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void parser_destroy(t_parser *parser) +{ + parser->state = SUCCESS; + ft_lstdel(&parser->stack, &ft_lst_cfree); + ft_lstdel(&parser->heredoc_queue, &ft_lst_cfree); + free(parser->new_sym); + parser->new_sym = NULL; + parser->cache = 0; +} diff --git a/42sh/src/parser/parser_init.c b/42sh/src/parser/parser_init.c new file mode 100644 index 00000000..002b9525 --- /dev/null +++ b/42sh/src/parser/parser_init.c @@ -0,0 +1,22 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* parser_init.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ariard +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/21 16:14:04 by ariard #+# #+# */ +/* Updated: 2017/03/29 15:43:52 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void parser_init(t_parser *parser) +{ + parser->state = SUCCESS; + parser->new_sym = NULL; + parser->cache = 0; + parser->stack = NULL; + parser->heredoc_queue = NULL; +} diff --git a/42sh/src/parser/pop_stack.c b/42sh/src/parser/pop_stack.c new file mode 100644 index 00000000..cfd8ac1b --- /dev/null +++ b/42sh/src/parser/pop_stack.c @@ -0,0 +1,36 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* pop_stack.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ariard +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/09 19:12:44 by ariard #+# #+# */ +/* Updated: 2017/03/18 17:16:00 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int pop_stack(t_list **stack, t_sym erase_sym) +{ + t_sym *head; + t_list *temp; + + while ((*stack) && (*(head = (*stack)->content) != erase_sym + && *head != TERMINUS)) + { + temp = *stack; + (*stack) = (*stack)->next; + ft_lstdelone(&temp, &sym_free); + } + if ((*stack) && *(head = (*stack)->content) != TERMINUS) + { + temp = *stack; + (*stack) = (*stack)->next; + ft_lstdelone(&temp, &sym_free); + } + else + return (1); + return (0); +} diff --git a/42sh/src/parser/produce_sym.c b/42sh/src/parser/produce_sym.c new file mode 100644 index 00000000..3a989fb5 --- /dev/null +++ b/42sh/src/parser/produce_sym.c @@ -0,0 +1,156 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* produce_sym.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ariard +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/09 17:58:34 by ariard #+# #+# */ +/* Updated: 2017/03/27 17:22:10 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static t_prodmatch g_prodmatch[] = +{ + {TK_WORD, TK_DLESS, HERE_END}, + {TK_WORD, TK_DLESSDASH, HERE_END}, + {TK_WORD, TK_LESS, FILENAME}, + {TK_WORD, TK_LESSAND, FILENAME}, + {TK_WORD, TK_GREAT, FILENAME}, + {TK_WORD, TK_GREATAND, FILENAME}, + {TK_WORD, TK_DGREAT, FILENAME}, + {TK_WORD, TK_LESSGREAT, FILENAME}, + {TK_WORD, TK_CLOBBER, FILENAME}, + {TK_WORD, CMD_WORD, CMD_SUFFIX}, + {TK_WORD, CMD_NAME, CMD_SUFFIX}, + {TK_WORD, CMD_SUPERIOR, CMD_SUFFIX}, + {TK_WORD, PIPE_SEMI_SEQUENCE, CMD_SUFFIX}, + {TK_WORD, LINEBREAK, CMD_NAME}, + {TK_WORD, TK_BANG, CMD_NAME}, + {TK_WORD, TK_PIPE, CMD_NAME}, + {TK_WORD, AND_OR, CMD_NAME}, + {TK_WORD, AND_OR_MAJOR, CMD_NAME}, + {TK_WORD, TK_PAREN_CLOSE, CMD_NAME}, + {TK_WORD, TK_WHILE, CMD_NAME}, + {TK_WORD, TK_UNTIL, CMD_NAME}, + {TK_WORD, TK_DO, CMD_NAME}, + {TK_WORD, TK_RBRACE, CMD_NAME}, + {TK_WORD, TK_IF, CMD_NAME}, + {TK_WORD, TK_THEN, CMD_NAME}, + {TK_WORD, TK_ELIF, CMD_NAME}, + {TK_WORD, TK_ELSE, CMD_NAME}, + {TK_WORD, COMPOUND_LIST, CMD_NAME}, + {TK_WORD, CASE_LIST_NS, CMD_NAME}, + {TK_WORD, COMPLETE_CONDITION, CMD_NAME}, + {TK_WORD, CONDITION, CMD_NAME}, + {TK_WORD, NEWLINE_LIST, CMD_NAME}, + {TK_WORD, TK_BANG, CMD_NAME}, + {TK_WORD, SEQUENCE, CMD_NAME}, + {TK_WORD, SEPARATOR_OP, CMD_NAME}, + {TK_WORD, TK_PAREN_OPEN, CMD_NAME}, + {TK_WORD, TK_LBRACE, CMD_NAME}, + {TK_WORD, CASE_LIST, PATTERN}, + {TK_WORD, PATTERN_CASE, PATTERN}, + {TK_WORD, COMPLETE_COMMANDS, CMD_NAME}, + {TK_ASSIGNMENT_WORD, TK_BANG, CMD_PREFIX}, + {TK_ASSIGNMENT_WORD, LINEBREAK, CMD_PREFIX}, + {TK_ASSIGNMENT_WORD, TK_PAREN_OPEN, CMD_PREFIX}, + {TK_ASSIGNMENT_WORD, TK_LBRACE, CMD_PREFIX}, + {TK_ASSIGNMENT_WORD, TK_BANG, CMD_PREFIX}, + {TK_ASSIGNMENT_WORD, SEPARATOR_OP, CMD_PREFIX}, + {TK_ASSIGNMENT_WORD, TK_WHILE, CMD_PREFIX}, + {TK_ASSIGNMENT_WORD, TK_UNTIL, CMD_PREFIX}, + {TK_ASSIGNMENT_WORD, TK_DO, CMD_PREFIX}, + {TK_ASSIGNMENT_WORD, TK_FOR, CMD_PREFIX}, + {TK_ASSIGNMENT_WORD, TK_IF, CMD_PREFIX}, + {TK_ASSIGNMENT_WORD, TK_THEN, CMD_PREFIX}, + {TK_ASSIGNMENT_WORD, TK_ELIF, CMD_PREFIX}, + {TK_ASSIGNMENT_WORD, TK_ELSE, CMD_PREFIX}, + {TK_ASSIGNMENT_WORD, NEWLINE_LIST, CMD_PREFIX}, + {TK_ASSIGNMENT_WORD, CMD_NAME, CMD_SUFFIX}, + {TK_ASSIGNMENT_WORD, CMD_SUPERIOR, CMD_SUFFIX}, + {TK_ASSIGNMENT_WORD, COMPOUND_LIST, CMD_PREFIX}, + {TK_ASSIGNMENT_WORD, COMPLETE_CONDITION, CMD_PREFIX}, + {TK_ASSIGNMENT_WORD, CONDITION, CMD_PREFIX}, + {TK_ASSIGNMENT_WORD, AND_OR, CMD_PREFIX}, + {TK_ASSIGNMENT_WORD, AND_OR_MAJOR, CMD_PREFIX}, + {TK_ASSIGNMENT_WORD, PIPE_SEMI_SEQUENCE, CMD_SUFFIX}, + {TK_ASSIGNMENT_WORD, SEQUENCE, CMD_PREFIX}, + {TK_ASSIGNMENT_WORD, COMPLETE_COMMANDS, CMD_PREFIX}, + {TK_ASSIGNMENT_WORD, CMD_WORD, CMD_SUFFIX}, + {TK_NAME, TK_BANG, FNAME}, + {TK_NAME, LINEBREAK, FNAME}, + {TK_NAME, TK_PAREN_OPEN, FNAME}, + {TK_NAME, TK_LBRACE, FNAME}, + {TK_NAME, TK_BANG, FNAME}, + {TK_NAME, SEPARATOR_OP, FNAME}, + {TK_NAME, NEWLINE_LIST, FNAME}, + {TK_NAME, TK_FOR, NAME}, + {TK_NEWLINE, CASE_LIST_NS, NEWLINE_LIST}, + {TK_NEWLINE, TK_DO, NEWLINE_LIST}, + {TK_NEWLINE, TK_PAREN_CLOSE, NEWLINE_LIST}, + {TK_NEWLINE, TK_RBRACE, CMD_NAME}, + {TK_NEWLINE, TK_IN, NEWLINE_LIST}, + {TK_NEWLINE, TK_WHILE, NEWLINE_LIST}, + {TK_NEWLINE, LOOP, NEWLINE_LIST}, + {TK_NEWLINE, TK_UNTIL, NEWLINE_LIST}, + {TK_NEWLINE, TK_FOR, NEWLINE_LIST}, + {TK_NEWLINE, TK_IF, NEWLINE_LIST}, + {TK_NEWLINE, TK_FI, NEWLINE_LIST}, + {TK_NEWLINE, TK_ELIF, NEWLINE_LIST}, + {TK_NEWLINE, TK_ELSE, NEWLINE_LIST}, + {TK_NEWLINE, TK_THEN, NEWLINE_LIST}, + {TK_NEWLINE, FUNC_NAME, NEWLINE_LIST}, + {TK_NEWLINE, CMD_NAME, NEWLINE_LIST}, + {TK_NEWLINE, COMPLETE_COMMANDS, NEWLINE_LIST}, + {TK_NEWLINE, LINEBREAK, NEWLINE_LIST}, + {TK_NEWLINE, TK_BANG, NEWLINE_LIST}, + {TK_NEWLINE, TK_PAREN_OPEN, NEWLINE_LIST}, + {TK_NEWLINE, TK_LBRACE, NEWLINE_LIST}, + {TK_NEWLINE, CMD_SUPERIOR, LINEBREAK}, + {TK_NEWLINE, PIPE_SEMI_SEQUENCE, LINEBREAK}, + {TK_NEWLINE, PIPE_CLOSE_SEQUENCE, LINEBREAK}, + {TK_NEWLINE, SEQUENCE, NEWLINE_LIST}, + {TK_NEWLINE, CASE_LIST_NS, NEWLINE_LIST}, + {TK_NEWLINE, COMPOUND_LIST, NEWLINE_LIST}, + {TK_NEWLINE, COMPLETE_CONDITION, NEWLINE_LIST}, + {TK_NEWLINE, CONDITION, NEWLINE_LIST}, + {TK_NEWLINE, FOR_WORDLIST, NEWLINE_LIST}, + {TK_NEWLINE, SEQUENTIAL_SEP, NEWLINE_LIST}, + {TK_NEWLINE, PROGRAM, NEWLINE_LIST}, + {TK_SEMI, CMD_SUPERIOR, SEPARATOR_OP}, + {TK_SEMI, LIST, SEPARATOR_OP}, + {TK_SEMI, PIPE_SEMI_SEQUENCE, SEPARATOR_OP}, + {TK_SEMI, PIPE_CLOSE_SEQUENCE, SEPARATOR_OP}, + {TK_AMP, CMD_SUPERIOR, SEPARATOR_OP}, + {TK_AMP, LIST, SEPARATOR_OP}, + {TK_AMP, PIPE_SEMI_SEQUENCE, SEPARATOR_OP}, + {TK_AMP, PIPE_CLOSE_SEQUENCE, SEPARATOR_OP}, + {0, 0, 0}, +}; + +int produce_sym(t_list **stack, t_sym *new_sym, t_list **lst) +{ + t_token *token; + t_sym *head; + int i; + + if (!*stack || !*lst) + return (1); + token = (*lst)->content; + head = (*stack)->content; + i = 0; + *new_sym = 0; + while (g_prodmatch[i].new_sym) + { + if (token->type == g_prodmatch[i].token + && *head == g_prodmatch[i].stack) + *new_sym = g_prodmatch[i].new_sym; + i++; + } + if (!*new_sym) + *new_sym = token->type; + return (0); +} diff --git a/42sh/src/parser/push_stack.c b/42sh/src/parser/push_stack.c new file mode 100644 index 00000000..7f74703e --- /dev/null +++ b/42sh/src/parser/push_stack.c @@ -0,0 +1,19 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* push_stack.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ariard +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/09 16:48:30 by ariard #+# #+# */ +/* Updated: 2017/03/26 21:35:32 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int push_stack(t_list **stack, t_sym sym) +{ + ft_lstadd(stack, ft_lstnew(&sym, sizeof(sym))); + return (0); +} diff --git a/42sh/src/parser/read_stack.c b/42sh/src/parser/read_stack.c new file mode 100644 index 00000000..de0f5b43 --- /dev/null +++ b/42sh/src/parser/read_stack.c @@ -0,0 +1,243 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* read_stack.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ariard +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/09 15:32:10 by ariard #+# #+# */ +/* Updated: 2017/03/29 17:03:04 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +char *read_state(t_sym current) +{ + if (current == AND_OR_MINOR) + return ("AND_OR_MINOR"); + if (current == AND_OR_MAJOR) + return ("AND_OR_MAJOR"); + if (current == FNAME) + return ("FNAME"); + if (current == PIPE_CLOSE_SEQUENCE) + return ("PIPE_CLOSE_SEQUENCE"); + if (current == TK_BANG) + return ("TK_BANG"); + if (current == OPEN_FUNC) + return ("OPEN_FUNC"); + if (current == CLOSE_FUNC) + return ("CLOSE_FUNC"); + if (current == HEREDOCDATA) + return ("HEREDOCDATA"); + if (current == TERMINUS) + return ("TERMINUS"); + if (current == SEQUENCE) + return ("SEQUENCE"); + if (current == LINEBREAK) + return ("LINEBREAK"); + if (current == CLOSE_LIST) + return ("CLOSE_LIST"); + if (current == BRACE_CLAUSE) + return ("BRACE_CLAUSE"); + if (current == FUNC_NAME) + return ("FUNC_NAME"); + if (current == TK_LBRACE) + return ("TK_LBRACE"); + if (current == TK_RBRACE) + return ("TK_RBRACE"); + if (current == TK_ASSIGNMENT_WORD) + return ("TK_ASSIGNMENT_WORD"); + if (current == CASE_CLAUSE) + return ("CASE_CLAUSE"); + if (current == CASE_LIST_NS) + return ("CASE_LIST_NS"); + if (current == TK_DSEMI) + return ("TK_DSEMI"); + if (current == TK_PAREN_OPEN) + return ("TK_PAREN_OPEN"); + if (current == TK_PAREN_CLOSE) + return ("TK_PAREN_CLOSE"); + if (current == FOR_WORDLIST) + return ("FOR_WORDLIST"); + if (current == FOR_CLAUSE) + return ("FOR_CLAUSE"); + if (current == TK_NAME) + return ("TK_NAME"); + if (current == TK_FOR) + return ("FOR"); + if (current == NAME) + return ("NAME"); + if (current == 0) + return ("NULL"); + if (current == PATTERN) + return ("PATTERN"); + if (current == TK_CASE) + return ("TK_CASE"); + if (current == TK_IN) + return ("TK_IN"); + if (current == TK_ESAC) + return ("TK_ESAC"); + if (current == UNTIL_CLAUSE) + return ("UNTIL_CLAUSE"); + if (current == TK_UNTIL) + return ("TK_UNTIL"); + if (current == IF_CLAUSE) + return ("IF_CLAUSE"); + if (current == CONDITION) + return ("CONDITION"); + if (current == COMPLETE_CONDITION) + return ("COMPLETE_CONDITION"); + if (current == TK_ELSE) + return ("TK_ELSE"); + if (current == TK_FI) + return ("TK_FI"); + if (current == ELSE_PART) + return ("ELSE_PART"); + if (current == TK_FI) + return ("TK_FI"); + if (current == TK_IF) + return ("TK_IF"); + if (current == TK_ELIF) + return ("TK_ELIF"); + if (current == TK_THEN) + return ("TK_THEN"); + if (current == COMPOUND_COMMAND) + return ("COMPOUND_COMMAND"); + if (current == WHILE_CLAUSE) + return ("WHILE_CLAUSE"); + if (current == LOOP) + return ("LOOP"); + if (current == TK_DONE) + return ("DONE"); + if (current == TK_DO) + return ("TK_DO"); + if (current == END_COMMAND) + return ("END_COMMAND"); + if (current == SEQUENTIAL_SEP) + return ("SEQUENTIAL_SEP"); + if (current == SEPARATOR) + return ("SEPARATOR"); + if (current == SEPARATOR_OP) + return ("SEPARATOR_OP"); + if (current == TERM) + return ("TERM"); + if (current == COMPOUND_LIST) + return ("COMPOUND_LIST"); + if (current == DO_GROUP) + return ("DO_GROUP"); + if (current == TK_NEWLINE) + return ("TK_NEWLINE"); + if (current == TK_WHILE) + return ("TK_WHILE"); + if (current == TK_DO) + return ("TK_DO"); + if (current == TK_DONE) + return ("TK_DONE"); + if (current == AND_OR_MINOR) + return ("AND_OR_MINOR"); + if (current == AND_OR_MAJOR) + return ("AND_OR_MAJOR"); + if (current == TK_COMMAND) + return ("TK_COMMAND"); + if (current == TK_AND_IF) + return ("TK_AND_IF"); + if (current == TK_OR_IF) + return ("TK_OR_IF"); + if (current == TK_AMP) + return ("TK_AMP"); + if (current == TK_PIPE) + return ("TK_PIPE"); + if (current == TK_LESS) + return ("TK_LESS"); + if (current == TK_GREAT) + return ("TK_GREAT"); + if (current == TK_DLESS) + return ("TK_DLESS"); + if (current == TK_DGREAT) + return ("TK_DGREAT"); + if (current == TK_DGREAT) + return ("TK_DGREAT"); + if (current == TK_LESSAND) + return ("TK_LESSAND"); + if (current == TK_GREATAND) + return ("TK_GREATAND"); + if (current == SUBSHELL) + return ("SUBSEHLL"); + if (current == CMD_SUPERIOR) + return ("CMD_SUPERIOR"); + if (current == TK_IO_NUMBER) + return ("IO_NUMBER"); + if (current == CMD_SUFFIX) + return ("CMD_SUFFIX"); + if (current == CMD_PREFIX) + return ("CMD_PREFIX"); + if (current == IO_REDIRECT) + return ("IO_REDIRECT"); + if (current == IO_FILE) + return ("IO_FILE"); + if (current == PIPE_SEMI_SEQUENCE) + return ("PIPE_SEMI_SEQUENCE"); + if (current == TK_PIPE) + return ("TK_PIPE"); + if (current == PROGRAM) + return ("PROGRAM"); + if (current == COMMAND) + return ("COMMAND"); + if (current == PIPE_SEQUENCE) + return ("PIPE_SEQUENCE"); + if (current == PIPELINE) + return ("PIPELINE"); + if (current == AND_OR) + return ("AND_OR"); + if (current == LIST) + return ("LIST"); + if (current == COMPLETE_COMMAND) + return ("COMPLETE_COMMAND"); + if (current == COMPLETE_COMMANDS) + return ("COMPLETE_COMMANDS"); + if (current == TK_WORD) + return ("TK_WORD"); + if (current == CMD_NAME) + return ("CMD_NAME"); + if (current == HERE_END) + return ("HERE_END"); + if (current == FILENAME) + return ("FILENAME"); + if (current == CMD_SUFFIX) + return ("CMD_SUFFIX"); + if (current == SIMPLE_COMMAND) + return ("SIMPLE_COMMAND"); + if (current == TK_SEMI) + return ("TK_SEMI"); + if (current == ALL) + return ("ALL"); + if (current == NEWLINE_LIST) + return ("NEWLINE_LIST"); + if (current == CMD) + return ("CMD"); + if (current != 0) + return ("NON-DEFINED"); + if (current == 0) + return ("NULL"); + return ("NULL"); +} + +int ft_read_stack(t_sym *stack) +{ + while (*stack) + DG("%s", read_state(*stack--)); + return (0); +} + +int ft_show_heredoc_data(t_astnode *node) +{ + t_redir *redir; + + if (node->type != CMD) + return (1); + redir = (node->data.cmd.redir)->content; + if (redir->type != TK_DLESS) + return (1); + return (0); +} diff --git a/42sh/src/parser/redir_init.c b/42sh/src/parser/redir_init.c new file mode 100644 index 00000000..02abcd56 --- /dev/null +++ b/42sh/src/parser/redir_init.c @@ -0,0 +1,23 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* redir_init.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ariard +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/17 17:46:50 by ariard #+# #+# */ +/* Updated: 2017/03/17 17:49:10 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int redir_init(t_type type, t_redir *redir) +{ + redir->n = (type == TK_LESS || type == TK_DLESS + || type == TK_LESSAND) ? STDIN : STDOUT; + redir->type = type; + redir->heredoc_data = NULL; + redir->word = NULL; + return (0); +} diff --git a/42sh/src/parser/stack_init.c b/42sh/src/parser/stack_init.c new file mode 100644 index 00000000..2bdf8bef --- /dev/null +++ b/42sh/src/parser/stack_init.c @@ -0,0 +1,22 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* stack_init.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ariard +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/16 20:31:32 by ariard #+# #+# */ +/* Updated: 2017/03/29 13:27:26 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int stack_init(t_parser *parser) +{ + push_stack(&parser->stack, TERMINUS); + push_stack(&parser->stack, LINEBREAK); + if (!parser->new_sym && !(parser->new_sym = ft_memalloc(sizeof(t_sym)))) + return (-1); + return (0); +} diff --git a/42sh/src/parser/sym_free.c b/42sh/src/parser/sym_free.c new file mode 100644 index 00000000..b26c2144 --- /dev/null +++ b/42sh/src/parser/sym_free.c @@ -0,0 +1,22 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* sym_free.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ariard +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/18 17:13:31 by ariard #+# #+# */ +/* Updated: 2017/03/20 14:57:58 by gwojda ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void sym_free(void *data, size_t size) +{ + t_sym *sym; + + (void)size; + sym = data; + free(sym); +} diff --git a/42sh/src/parser/tree_func_free.c b/42sh/src/parser/tree_func_free.c new file mode 100644 index 00000000..88154d66 --- /dev/null +++ b/42sh/src/parser/tree_func_free.c @@ -0,0 +1,23 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* tree_func_free.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ariard +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/21 19:02:54 by ariard #+# #+# */ +/* Updated: 2017/03/21 19:44:21 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void tree_func_free(void *data, size_t content_size) +{ + t_btree **root; + + (void)content_size; + root = data; + btree_del(root, &ast_free); + free(root); +} diff --git a/42sh/src/parser/tree_wrapper.c b/42sh/src/parser/tree_wrapper.c new file mode 100644 index 00000000..f056cdb8 --- /dev/null +++ b/42sh/src/parser/tree_wrapper.c @@ -0,0 +1,64 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* tree_wrapper.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ariard +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/15 18:57:44 by ariard #+# #+# */ +/* Updated: 2017/03/24 15:00:14 by ariard ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int join_ast(t_btree **ast, t_btree **new_node) +{ + (*new_node)->left = *ast; + *ast = *new_node; + return (0); +} + +int gen_node(t_btree **ast) +{ + t_astnode item; + + if (!*ast) + { + *ast = btree_create_node(&item, sizeof(item)); + ft_bzero((void *)&((t_astnode *)(*ast)->item)->data, sizeof(t_astdata)); + ((t_astnode *)(*ast)->item)->nest = 0; + ((t_astnode *)(*ast)->item)->full = 0; + ((t_astnode *)(*ast)->item)->cache = 0; + ((t_astnode *)(*ast)->item)->type = TK_NEWLINE; + ((t_astnode *)(*ast)->item)->pattern = 0; + } + return (0); +} + +int isnull(t_btree **ast, t_list **lst) +{ + (void)ast; + (void)lst; + return (-1); +} + +int add_null(t_btree **ast, t_list **lst) +{ + (void)ast; + (void)lst; + return (-1); +} + +int add_branch(t_btree **ast, t_list **lst) +{ + t_astnode *node; + t_btree *new_node; + + new_node = NULL; + gen_node(&new_node); + join_ast(ast, &new_node); + node = (new_node)->item; + node->type = TK_NEWLINE; + return (add_cmd(ast, lst)); +}