diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..03182c0 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,16 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "lldb", + "request": "launch", + "name": "Debug", + "program": "${workspaceFolder}/minishell", + "args": [], + "cwd": "${workspaceFolder}" + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 4a06854..6342c52 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,7 @@ { "files.associations": { "minishell.h": "c", - "readline.h": "c" + "readline.h": "c", + "struct.h": "c" } } \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..08d9005 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,28 @@ +{ + "tasks": [ + { + "type": "cppbuild", + "label": "C/C++: gcc build active file", + "command": "/usr/bin/gcc", + "args": [ + "-fdiagnostics-color=always", + "-g", + "${file}", + "-o", + "${fileDirname}/${fileBasenameNoExtension}" + ], + "options": { + "cwd": "${fileDirname}" + }, + "problemMatcher": [ + "$gcc" + ], + "group": { + "kind": "build", + "isDefault": true + }, + "detail": "Task generated by Debugger." + } + ], + "version": "2.0.0" +} \ No newline at end of file diff --git a/Libft/Makefile b/Libft/Makefile deleted file mode 100644 index 1b49a31..0000000 --- a/Libft/Makefile +++ /dev/null @@ -1,78 +0,0 @@ -# **************************************************************************** # -# # -# ::: :::::::: # -# Makefile :+: :+: :+: # -# +:+ +:+ +:+ # -# By: eunwolee +#+ +:+ +#+ # -# +#+#+#+#+#+ +#+ # -# Created: 2022/11/17 12:21:51 by eunwolee #+# #+# # -# Updated: 2023/07/10 19:30:40 by eunwolee ### ########.fr # -# # -# **************************************************************************** # - -NAME = libft.a - -CC = cc -CFLAGS = -Wall -Wextra -Werror -AR = ar rcs -RM = rm -f - -SRCS = ft_isalpha.c \ - ft_isdigit.c \ - ft_isalnum.c \ - ft_isascii.c \ - ft_isprint.c \ - ft_toupper.c \ - ft_tolower.c \ - ft_memcmp.c \ - ft_memset.c \ - ft_memchr.c \ - ft_memcpy.c \ - ft_memmove.c \ - ft_calloc.c \ - ft_bzero.c \ - ft_strlen.c \ - ft_strlcpy.c \ - ft_strlcat.c \ - ft_strncat.c \ - ft_strchr.c \ - ft_strrchr.c \ - ft_strnstr.c \ - ft_strdup.c \ - ft_strncmp.c \ - ft_atoi.c \ - ft_substr.c \ - ft_strjoin.c \ - ft_strtrim.c \ - ft_split.c \ - ft_itoa.c \ - ft_strmapi.c \ - ft_striteri.c \ - ft_putchar_fd.c \ - ft_putstr_fd.c \ - ft_putendl_fd.c \ - ft_putnbr_fd.c \ - get_next_line.c \ - get_next_line_utils.c - -OBJS = $(SRCS:%.c=%.o) - -all: $(NAME) - -$(NAME): $(OBJS) - $(AR) $@ $^ - -%.o: %.c - $(CC) $(CFLAGS) -c $^ -I . - -clean: - $(RM) $(OBJS) - -fclean: clean - $(RM) $(NAME) - -re: - $(MAKE) fclean - $(MAKE) all - -.PHONY: all clean fclean re diff --git a/Libft/ft_atoi.c b/Libft/ft_atoi.c deleted file mode 100644 index 3e0ce61..0000000 --- a/Libft/ft_atoi.c +++ /dev/null @@ -1,31 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* ft_atoi.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: eunwolee +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2022/11/12 17:50:40 by eunwolee #+# #+# */ -/* Updated: 2022/11/22 16:00:54 by eunwolee ### ########.fr */ -/* */ -/* ************************************************************************** */ - -int ft_atoi(const char *str) -{ - int res; - int sign; - - res = 0; - sign = 1; - while ((*str >= 9 && *str <= 13) || *str == 32) - str++; - if (*str == '+' || *str == '-') - { - if (*str == '-') - sign *= -1; - str++; - } - while (*str >= '0' && *str <= '9') - res = (res * 10) + (*str++ - '0'); - return (res * sign); -} diff --git a/Libft/ft_isascii.c b/Libft/ft_isascii.c deleted file mode 100644 index 5fd8dd2..0000000 --- a/Libft/ft_isascii.c +++ /dev/null @@ -1,18 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* ft_isascii.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: eunwolee +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2022/11/09 18:26:14 by eunwolee #+# #+# */ -/* Updated: 2022/11/14 18:22:39 by eunwolee ### ########.fr */ -/* */ -/* ************************************************************************** */ - -int ft_isascii(int c) -{ - if (c >= 0 && c <= 127) - return (1); - return (0); -} diff --git a/Libft/ft_isprint.c b/Libft/ft_isprint.c deleted file mode 100644 index ca57df1..0000000 --- a/Libft/ft_isprint.c +++ /dev/null @@ -1,18 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* ft_isprint.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: eunwolee +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2022/11/09 18:35:25 by eunwolee #+# #+# */ -/* Updated: 2022/11/14 20:25:14 by eunwolee ### ########.fr */ -/* */ -/* ************************************************************************** */ - -int ft_isprint(int c) -{ - if (c >= 32 && c <= 126) - return (1); - return (0); -} diff --git a/Libft/ft_memcmp.c b/Libft/ft_memcmp.c deleted file mode 100644 index e5b430e..0000000 --- a/Libft/ft_memcmp.c +++ /dev/null @@ -1,30 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* ft_memcmp.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: eunwolee +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2022/11/09 21:07:36 by eunwolee #+# #+# */ -/* Updated: 2022/11/26 17:20:33 by eunwolee ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "libft.h" - -int ft_memcmp(const void *s1, const void *s2, size_t n) -{ - const unsigned char *str1; - const unsigned char *str2; - - str1 = (const unsigned char *)s1; - str2 = (const unsigned char *)s2; - while (n--) - { - if (*str1 != *str2) - return (*str1 - *str2); - str1++; - str2++; - } - return (0); -} diff --git a/Libft/ft_memcpy.c b/Libft/ft_memcpy.c deleted file mode 100644 index dc64629..0000000 --- a/Libft/ft_memcpy.c +++ /dev/null @@ -1,27 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* ft_memcpy.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: eunwolee +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2022/11/11 14:09:56 by eunwolee #+# #+# */ -/* Updated: 2022/11/23 22:50:36 by eunwolee ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "libft.h" - -void *ft_memcpy(void *dst, const void *src, size_t n) -{ - unsigned char *dest; - const unsigned char *source; - - if (!dst && !src) - return (0); - dest = (unsigned char *)dst; - source = (const unsigned char *)src; - while (n--) - *dest++ = *source++; - return (dst); -} diff --git a/Libft/ft_memmove.c b/Libft/ft_memmove.c deleted file mode 100644 index 1f9c422..0000000 --- a/Libft/ft_memmove.c +++ /dev/null @@ -1,31 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* ft_memmove.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: eunwolee +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2022/11/11 17:43:24 by eunwolee #+# #+# */ -/* Updated: 2022/11/23 22:52:37 by eunwolee ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "libft.h" - -void *ft_memmove(void *dst, const void *src, size_t len) -{ - unsigned char *dest; - const unsigned char *source; - - if (!dst && !src) - return (0); - dest = (unsigned char *)dst; - source = (const unsigned char *)src; - if (dest > source) - while (len--) - *(dest + len) = *(source + len); - else - while (len--) - *dest++ = *source++; - return (dst); -} diff --git a/Libft/ft_putchar_fd.c b/Libft/ft_putchar_fd.c deleted file mode 100644 index 7fb1548..0000000 --- a/Libft/ft_putchar_fd.c +++ /dev/null @@ -1,20 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* ft_putchar_fd.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: eunwolee +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2022/11/15 15:41:40 by eunwolee #+# #+# */ -/* Updated: 2022/11/17 12:34:30 by eunwolee ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "libft.h" - -void ft_putchar_fd(char c, int fd) -{ - if (fd < 0) - return ; - write (fd, &c, 1); -} diff --git a/Libft/ft_putnbr_fd.c b/Libft/ft_putnbr_fd.c deleted file mode 100644 index d3e5e80..0000000 --- a/Libft/ft_putnbr_fd.c +++ /dev/null @@ -1,40 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* ft_putnbr_fd.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: eunwolee +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2022/11/16 21:49:13 by eunwolee #+# #+# */ -/* Updated: 2022/11/17 14:47:44 by eunwolee ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "libft.h" - -void ft_putnbr_fd(int n, int fd) -{ - char num; - - if (fd < 0) - return ; - if (n == -2147483648) - { - write(fd, "-2147483648", 11); - return ; - } - if (n < 0) - { - write (fd, "-", 1); - n *= -1; - } - if (n < 10) - { - num = n + '0'; - write (fd, &num, 1); - return ; - } - ft_putnbr_fd(n / 10, fd); - num = n % 10 + '0'; - write(fd, &num, 1); -} diff --git a/Libft/ft_putstr_fd.c b/Libft/ft_putstr_fd.c deleted file mode 100644 index d3be0c6..0000000 --- a/Libft/ft_putstr_fd.c +++ /dev/null @@ -1,20 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* ft_putstr_fd.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: eunwolee +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2022/11/15 16:25:54 by eunwolee #+# #+# */ -/* Updated: 2022/11/17 14:45:35 by eunwolee ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "libft.h" - -void ft_putstr_fd(char *s, int fd) -{ - if (fd < 0) - return ; - write(fd, s, ft_strlen(s)); -} diff --git a/Libft/ft_strchr.c b/Libft/ft_strchr.c deleted file mode 100644 index 5200892..0000000 --- a/Libft/ft_strchr.c +++ /dev/null @@ -1,27 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* ft_strchr.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: eunwolee +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2022/11/12 17:03:53 by eunwolee #+# #+# */ -/* Updated: 2022/11/23 20:24:50 by eunwolee ### ########.fr */ -/* */ -/* ************************************************************************** */ - -char *ft_strchr(const char *s, int c) -{ - unsigned char ch; - - ch = (unsigned char) c; - while (*s) - { - if (*s == ch) - return ((char *)s); - s++; - } - if (*s == ch) - return ((char *)s); - return (0); -} diff --git a/Libft/ft_strmapi.c b/Libft/ft_strmapi.c deleted file mode 100644 index 5b493b0..0000000 --- a/Libft/ft_strmapi.c +++ /dev/null @@ -1,31 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* ft_strmapi.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: eunwolee +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2022/11/15 12:58:33 by eunwolee #+# #+# */ -/* Updated: 2022/11/26 17:05:28 by eunwolee ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "libft.h" - -char *ft_strmapi(char const *s, char (*f)(unsigned int, char)) -{ - int idx; - char *dest; - - dest = (char *)malloc(sizeof(char) * (ft_strlen(s) + 1)); - if (!dest) - return (0); - idx = 0; - while (s[idx]) - { - dest[idx] = f(idx, s[idx]); - idx++; - } - dest[idx] = '\0'; - return (dest); -} diff --git a/Libft/ft_strnstr.c b/Libft/ft_strnstr.c deleted file mode 100644 index d719a2b..0000000 --- a/Libft/ft_strnstr.c +++ /dev/null @@ -1,38 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* ft_strnstr.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: eunwolee +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2022/11/12 17:16:09 by eunwolee #+# #+# */ -/* Updated: 2023/04/06 19:28:36 by eunwolee ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "libft.h" - -char *ft_strnstr(const char *haystack, const char *needle, size_t len) -{ - size_t idx; - size_t h_len; - size_t n_len; - - idx = 0; - if (!*needle) - return ((char *)haystack); - if (!len) - return (0); - h_len = ft_strlen(haystack); - n_len = ft_strlen(needle); - if (len < n_len || h_len < n_len) - return (0); - while (idx <= len - n_len && *haystack) - { - if (!ft_strncmp(haystack, needle, n_len)) - return ((char *)haystack); - idx++; - haystack++; - } - return (0); -} diff --git a/Libft/ft_strrchr.c b/Libft/ft_strrchr.c deleted file mode 100644 index c2cdf10..0000000 --- a/Libft/ft_strrchr.c +++ /dev/null @@ -1,31 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* ft_strrchr.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: eunwolee +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2022/11/12 17:11:16 by eunwolee #+# #+# */ -/* Updated: 2022/11/23 20:46:02 by eunwolee ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "libft.h" - -char *ft_strrchr(const char *s, int c) -{ - const char *tmp; - unsigned char ch; - - tmp = 0; - ch = (unsigned char) c; - while (*s) - { - if (*s == ch) - tmp = s; - s++; - } - if (*s == ch) - tmp = s; - return ((char *)tmp); -} diff --git a/Libft/ft_strtrim.c b/Libft/ft_strtrim.c deleted file mode 100644 index 0bc375e..0000000 --- a/Libft/ft_strtrim.c +++ /dev/null @@ -1,55 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* ft_strtrim.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: eunwolee +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2022/11/20 14:30:50 by eunwolee #+# #+# */ -/* Updated: 2022/12/02 15:49:00 by eunwolee ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "libft.h" - -static const char *from_front(char const *s1, char const *set, int *size) -{ - while (*s1) - { - if (!ft_strchr(set, *s1)) - break ; - s1++; - *size -= 1; - } - return (s1); -} - -static void from_back(char const *tmp, char const *set, int *size) -{ - while (*tmp) - { - if (!ft_strchr(set, *tmp)) - break ; - tmp--; - *size -= 1; - } -} - -char *ft_strtrim(char const *s1, char const *set) -{ - int size; - char *dest; - char const *tmp; - - size = ft_strlen(s1); - s1 = from_front(s1, set, &size); - tmp = s1; - tmp += size - 1; - if (size) - from_back(tmp, set, &size); - dest = (char *)malloc(sizeof(char) * (size + 1)); - if (!dest) - return (0); - ft_strlcpy(dest, s1, size + 1); - return (dest); -} diff --git a/Libft/ft_tolower.c b/Libft/ft_tolower.c deleted file mode 100644 index b5b54b4..0000000 --- a/Libft/ft_tolower.c +++ /dev/null @@ -1,18 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* ft_tolower.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: eunwolee +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2022/11/09 18:50:14 by eunwolee #+# #+# */ -/* Updated: 2022/11/14 20:30:06 by eunwolee ### ########.fr */ -/* */ -/* ************************************************************************** */ - -int ft_tolower(int c) -{ - if (c >= 'A' && c <= 'Z') - return (c + 32); - return (c); -} diff --git a/Libft/ft_toupper.c b/Libft/ft_toupper.c deleted file mode 100644 index fc084ac..0000000 --- a/Libft/ft_toupper.c +++ /dev/null @@ -1,18 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* ft_toupper.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: eunwolee +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2022/11/09 18:47:05 by eunwolee #+# #+# */ -/* Updated: 2022/11/14 20:30:09 by eunwolee ### ########.fr */ -/* */ -/* ************************************************************************** */ - -int ft_toupper(int c) -{ - if (c >= 'a' && c <= 'z') - return (c - 32); - return (c); -} diff --git a/Libft/get_next_line.c b/Libft/get_next_line.c deleted file mode 100644 index 6500a3a..0000000 --- a/Libft/get_next_line.c +++ /dev/null @@ -1,138 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* get_next_line.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: eunwolee +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2022/12/26 16:01:43 by eunwolee #+# #+# */ -/* Updated: 2023/07/12 19:41:52 by eunwolee ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "libft.h" - -static t_g_list *get_new_nod(int fd) -{ - char *buff; - t_g_list *nod; - - buff = (char *)malloc(sizeof(char) * 1); - if (!buff) - return (0); - buff[0] = '\0'; - nod = (t_g_list *)malloc(sizeof(t_g_list) * 1); - if (!nod) - { - free(buff); - return (0); - } - nod->buff = buff; - nod->fd = fd; - nod->next = 0; - return (nod); -} - -static t_g_list *get_fd_nod(t_g_list **head, int fd) -{ - t_g_list *tmp; - - tmp = *head; - if (!tmp) - { - tmp = get_new_nod(fd); - if (!tmp) - return (0); - *head = tmp; - } - while (tmp->next) - { - if (tmp->fd == fd) - return (tmp); - tmp = tmp->next; - } - if (tmp->fd != fd) - { - tmp->next = get_new_nod(fd); - if (!tmp->next) - return (0); - tmp = tmp->next; - } - return (tmp); -} - -static char *get_done_line(t_g_list *nod) -{ - int idx; - int nod_cnt; - int line_cnt; - char *line; - - line_cnt = 0; - while (nod->buff[line_cnt] != '\n' && nod->buff[line_cnt]) - line_cnt++; - if (nod->buff[line_cnt] == '\n') - line_cnt++; - nod_cnt = ft_strlen(&nod->buff[line_cnt]); - line = (char *)malloc(sizeof(char) * (line_cnt + 1)); - if (!line) - return (0); - idx = -1; - while (++idx < line_cnt) - line[idx] = nod->buff[idx]; - idx = -1; - while (++idx < nod_cnt) - nod->buff[idx] = nod->buff[idx + line_cnt]; - line[line_cnt] = '\0'; - nod->buff[nod_cnt] = '\0'; - return (line); -} - -static int get_read_line(int fd, t_g_list *nod) -{ - int rd; - char *buff; - - buff = (char *)malloc(sizeof(char) * BUFFER_SIZE + 1); - if (!buff) - return (-1); - rd = 1; - while (rd) - { - rd = read(fd, buff, BUFFER_SIZE); - if (rd == -1 || !rd) - break ; - buff[rd] = '\0'; - nod->buff = ft_strjoin(nod->buff, buff); - if (!nod->buff) - { - free(buff); - return (-1); - } - if (ft_strchr(nod->buff, '\n')) - break ; - } - free(buff); - return (rd); -} - -char *get_next_line(int fd) -{ - t_g_list *nod; - char *line; - static t_g_list *head; - - if (fd < 0 || BUFFER_SIZE <= 0) - return (0); - nod = get_fd_nod(&head, fd); - if (!nod) - return (0); - if (get_read_line(fd, nod) == -1 || !*(nod->buff)) - return (delete_nod(&head, nod)); - line = get_done_line(nod); - if (!line) - return (delete_nod(&head, nod)); - if (!*(nod->buff)) - delete_nod(&head, nod); - return (line); -} diff --git a/Libft/get_next_line_utils.c b/Libft/get_next_line_utils.c deleted file mode 100644 index ec97127..0000000 --- a/Libft/get_next_line_utils.c +++ /dev/null @@ -1,36 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* get_next_line_utils.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: eunwolee +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2022/12/26 16:01:47 by eunwolee #+# #+# */ -/* Updated: 2023/07/10 19:31:14 by eunwolee ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "libft.h" - -char *delete_nod(t_g_list **head, t_g_list *nod) -{ - t_g_list *tmp; - - tmp = *head; - if (tmp == nod) - { - if (!(tmp->next)) - *head = 0; - else - *head = tmp->next; - free(nod->buff); - free(nod); - return (0); - } - while (tmp->next != nod) - tmp = tmp->next; - tmp->next = nod->next; - free(nod->buff); - free(nod); - return (0); -} diff --git a/Makefile b/Makefile index b31583f..1b883ea 100644 --- a/Makefile +++ b/Makefile @@ -5,62 +5,116 @@ L_NAME = libft.a INCS_DIR = incs SRCS_DIR = srcs +OBJS_DIR = objs +READ_DIR = ~/.brew/opt/readline CC = cc -CFLAGS = -Wall -Wextra -Werror -I ~/.brew/opt/readline/include +CFLAGS = -Wall -Wextra -Werror -I $(READ_DIR)/include +RLFLAGS = -lreadline -ltermcap RM = rm -rf MAKE = make -SRCS = $(SRCS_DIR)/minishell.c \ - $(SRCS_DIR)/init/init.c \ - $(SRCS_DIR)/lexer/lexer.c \ - $(SRCS_DIR)/lexer/tokenizer.c \ - $(SRCS_DIR)/lexer/quote.c \ - $(SRCS_DIR)/lexer/expand.c \ - $(SRCS_DIR)/parser/syntax.c \ - $(SRCS_DIR)/parser/parser.c \ - $(SRCS_DIR)/utils/env.c \ - $(SRCS_DIR)/utils/list.c \ - $(SRCS_DIR)/utils/list_clear.c \ - $(SRCS_DIR)/utils/tree.c \ - $(SRCS_DIR)/utils/utils.c \ - $(SRCS_DIR)/utils/temp.c \ - $(SRCS_DIR)/exec/sig.c \ - $(SRCS_DIR)/builtin/ft_cd.c \ - $(SRCS_DIR)/builtin/ft_echo.c \ - $(SRCS_DIR)/builtin/ft_exit.c \ - $(SRCS_DIR)/builtin/ft_pwd.c \ - $(SRCS_DIR)/builtin/ft_unset.c \ - $(SRCS_DIR)/builtin/ft_export.c \ +SRCS = minishell.c \ + init/init.c \ + input/get_input.c \ + lexer/lexer.c \ + lexer/tokenizer.c \ + lexer/quote.c \ + lexer/expand.c \ + lexer/expand_check.c \ + lexer/lexer_utils.c \ + parser/syntax.c \ + parser/parser.c \ + builtin/builtin.c \ + builtin/ft_cd.c \ + builtin/ft_echo.c \ + builtin/ft_exit.c \ + builtin/ft_pwd.c \ + builtin/ft_unset.c \ + builtin/ft_export.c \ + builtin/ft_export_print.c \ + builtin/ft_export_check.c \ + builtin/ft_env.c \ + builtin/ft_atolong.c \ + builtin/ft_join_cmd.c \ + builtin/ft_cnt_args.c \ + builtin/ft_update_env_cd.c \ + builtin/ft_update_env_export.c \ + builtin/ft_add_env_front.c \ + execute/execve.c \ + execute/execve_utils.c \ + execute/child.c \ + execute/parent.c \ + execute/pipe.c \ + execute/path.c \ + execute/file.c \ + redirect/heredoc.c \ + redirect/heredoc_parser.c \ + redirect/redirect.c \ + signal/signal.c \ + utils/error.c \ + utils/env.c \ + utils/list.c \ + utils/list_clear.c \ + utils/tree.c \ + utils/free.c \ + Libft/ft_isalpha.c \ + Libft/ft_isalnum.c \ + Libft/ft_isdigit.c \ + Libft/ft_itoa.c \ + Libft/ft_split.c \ + Libft/ft_substr.c \ + Libft/ft_strjoin.c \ + Libft/ft_strncmp.c \ + Libft/ft_strncat.c \ + Libft/ft_strdup.c \ + Libft/ft_strlen.c \ + Libft/ft_strlcat.c \ + Libft/ft_strlcpy.c \ + Libft/ft_calloc.c \ + Libft/ft_memset.c \ + Libft/ft_putendl_fd.c \ - -OBJS = $(SRCS:%.c=%.o) - -%.o: %.c - $(CC) $(CFLAGS) -c $^ -o $@ -I $(INCS_DIR) +SRCS_WITH_PATH = $(addprefix $(SRCS_DIR)/, $(SRCS)) +OBJS = $(SRCS_WITH_PATH:$(SRCS_DIR)/%.c=$(OBJS_DIR)/%.o) all: $(NAME) -$(NAME): $(L_NAME) $(OBJS) - $(CC) $^ -o $@ -I $(INCS_DIR) -lreadline -L ~/.brew/opt/readline/lib +${OBJS_DIR}/%.o: ${SRCS_DIR}/%.c | ${OBJS_DIR} + @$(CC) $(CFLAGS) -c $^ -o $@ -I $(INCS_DIR) + +${OBJS_DIR}: + @echo "*---MINISHELL BUILD---*" + @mkdir ${OBJS_DIR} + @mkdir ${OBJS_DIR}/init + @mkdir ${OBJS_DIR}/input + @mkdir ${OBJS_DIR}/lexer + @mkdir ${OBJS_DIR}/parser + @mkdir ${OBJS_DIR}/utils + @mkdir ${OBJS_DIR}/builtin + @mkdir ${OBJS_DIR}/execute + @mkdir ${OBJS_DIR}/redirect + @mkdir ${OBJS_DIR}/signal + @mkdir ${OBJS_DIR}/Libft -$(L_NAME): - $(MAKE) re -C $(L_DIR) - cp ./$(L_DIR)/$(L_NAME) . +$(NAME): $(OBJS) + @echo "MINISHELL DONE" + @$(CC) $(RLFLAGS) $^ -o $@ -I $(INCS_DIR) -L $(READ_DIR)/lib clean: - $(MAKE) fclean -C $(L_DIR) - $(RM) $(OBJS) - $(RM) $(SRCS_DIR_M)/*.o $(SRCS_DIR_B)/*.o $(L_NAME) + @echo "MINISHELL CLEAN" + @$(RM) $(OBJS_DIR) + @$(RM) $(L_NAME) fclean: - $(MAKE) fclean -C $(L_DIR) - $(MAKE) clean - $(RM) $(NAME) + @$(MAKE) clean + @echo "MINISHELL FCLEAN" + @$(RM) $(NAME) re: - $(MAKE) fclean - $(MAKE) all + @echo "*------RE_BUILD-------*" + @$(MAKE) fclean + @$(MAKE) all .PHONY: all clean fclean re \ No newline at end of file diff --git a/incs/builtin.h b/incs/builtin.h new file mode 100644 index 0000000..70a0b58 --- /dev/null +++ b/incs/builtin.h @@ -0,0 +1,58 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* builtin.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: eunwolee +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/08/16 21:22:15 by eunwolee #+# #+# */ +/* Updated: 2023/08/17 11:16:46 by eunwolee ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef BUILTIN_H +# define BUILTIN_H + +# include "struct.h" + +# define LLONG_MAX 9223372036854775807 +# define LLONG_MIN -9223372036854775808ULL + +/*builtin*/ +int check_builtin_func(char *name); +int exec_builtin(int builtnum, t_data *data); + +void ft_pwd(void); +t_bool ft_cd(t_data *data); +void ft_echo(t_leaf *arg); +void ft_exit(t_data *data); +t_bool ft_env(t_data *data); + +/*ft_export*/ +t_bool ft_export(t_data *data, t_leaf *cmd); +void free_d_char_ptr(char **str); + +/*ft_unset*/ +void ft_unset(t_data *data, t_leaf *cur_root); +void update_env_double_char(t_data *data); + +int ft_cnt_args(char **args); +char **ft_join_cmd(t_leaf *leaf); +long long ft_atolong(char *str, int *flag); +void ft_add_env_front(t_data *head, char *key, char *value); +void ft_update_env_cd(t_data *data, char *key, char *value); +void ft_update_env_export(t_data *data, char *key, char *value); + +/*ft_export_print*/ +void print_export_order(t_data *data); +void devide_equal(char *src, char **str1, char **str2, \ + t_bool key_need_equal); + +/*ft_export_check*/ +t_bool check_env(t_data *data, char *key, char *value); +int check_plus(char *str); +int check_name(char *str); +int check_equal(char *str); +int check_underbar(char ch); + +#endif \ No newline at end of file diff --git a/incs/exec.h b/incs/exec.h deleted file mode 100644 index 7ab737c..0000000 --- a/incs/exec.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef EXEC_H -# define EXEC_H - -# include "../incs/struct.h" - -void sig(char *command); -void sig_init(void); -void ft_cd(t_data *data); -void ft_echo(t_data *data); -void ft_exit(t_data *data); -void ft_pwd(); -void ft_unset(t_data *data); -void ft_export(t_data *data); -char **join_cmd(t_leaf * com_leaf); -int count_args(char **args); -void update_env(t_data *data, char *key, char *value); -t_list *env_search(t_data *data, char *key); -void print_export_order(t_data *data); - -#endif \ No newline at end of file diff --git a/incs/execute.h b/incs/execute.h new file mode 100644 index 0000000..7b9234f --- /dev/null +++ b/incs/execute.h @@ -0,0 +1,60 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* execute.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: kichlee +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/08/08 17:49:19 by eunwolee #+# #+# */ +/* Updated: 2023/08/17 22:06:22 by kichlee ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef EXECUTE_H +# define EXECUTE_H + +# include "struct.h" + +t_bool get_input(t_data *data); + +void execute(t_data *data); +void execute_cmd(t_data *data, int flag); + +/*execve utils*/ +int check_builtin(t_data *data); +void recover_std(t_data *data); +void heredoc_flag(t_leaf *leaf, t_data *data); + +/*child*/ +void do_cmd(t_data *data); +void exec_fork(t_data *data); +t_bool check_dir(char *command); + +/*parent*/ +void wait_child_processes(t_data *data); + +int check_redirect(t_leaf *leaf, t_data *data); + +int fork_heredoc(t_data *data); + +/*heredoc_uilts*/ +void write_str(t_data *data, char *content, int fd); + +char *set_path(t_data *data); +void abs_path(t_data *data); +char *search_path(t_pipe *base); +int check_path(char *str); + +int check_file(int fd, t_data *data); +void close_file(t_data *data); + +void sig(void); +void handle_sigint(int sig); +void init_base(int ac); +void child_handler(int signum); + +int link_pipe(int i, t_pipe *base, t_data *data); +void close_pipe(int i, t_pipe *base, t_data *data); +void count_pipe(t_data *data); + +#endif \ No newline at end of file diff --git a/Libft/ft_bzero.c b/incs/init.h similarity index 64% rename from Libft/ft_bzero.c rename to incs/init.h index 2df6ce3..1a216c3 100644 --- a/Libft/ft_bzero.c +++ b/incs/init.h @@ -1,22 +1,23 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* ft_bzero.c :+: :+: :+: */ +/* init.h :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: eunwolee +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ -/* Created: 2022/11/12 15:33:02 by eunwolee #+# #+# */ -/* Updated: 2022/11/26 16:38:32 by eunwolee ### ########.fr */ +/* Created: 2023/07/11 10:29:44 by eunwolee #+# #+# */ +/* Updated: 2023/08/15 00:45:00 by eunwolee ### ########.fr */ /* */ /* ************************************************************************** */ -#include "libft.h" +#ifndef INIT_H +# define INIT_H -void ft_bzero(void *s, size_t n) -{ - unsigned char *str; +# include "struct.h" - str = (unsigned char *)s; - while (n--) - *str++ = 0; -} +void init(t_data **data, char **envp); +void env_init(t_data *data, char **envp); +void pipe_init(t_pipe **pipe); +void info_init(t_info **info); + +#endif \ No newline at end of file diff --git a/Libft/libft.h b/incs/libft.h similarity index 58% rename from Libft/libft.h rename to incs/libft.h index db6e378..a762118 100644 --- a/Libft/libft.h +++ b/incs/libft.h @@ -6,7 +6,7 @@ /* By: eunwolee +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/11/07 21:00:01 by eunwolee #+# #+# */ -/* Updated: 2023/07/12 19:42:12 by eunwolee ### ########.fr */ +/* Updated: 2023/08/17 13:10:28 by eunwolee ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,57 +17,21 @@ # include # include -# ifndef BUFFER_SIZE -# define BUFFER_SIZE 42 -# endif - -typedef struct s_g_list -{ - int fd; - char *buff; - struct s_g_list *next; -} t_g_list; - -char *get_next_line(int fd); -char *delete_nod(t_g_list **head, t_g_list *nod); - -//Libc functions 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); -int ft_memcmp(const void *s1, const void *s2, size_t n); void *ft_memset(void *b, int c, size_t len); -void *ft_memchr(const void *s, int c, size_t n); -void *ft_memcpy(void *dst, const void *src, size_t n); -void *ft_memmove(void *dst, const void *src, size_t len); void *ft_calloc(size_t count, size_t size); -void ft_bzero(void *s, size_t n); size_t ft_strlen(const char *s); size_t ft_strlcpy(char *dst, const char *src, size_t dstsize); size_t ft_strlcat(char *dst, const char *src, size_t dstsize); char *ft_strncat(char *dest, char *src, int n); -char *ft_strchr(const char *s, int c); -char *ft_strrchr(const char *s, int c); -char *ft_strnstr(const char *haystack, const char *needle, size_t len); char *ft_strdup(const char *s1); int ft_strncmp(const char *s1, const char *s2, size_t n); -int ft_atoi(const char *str); - -//Additional functions char *ft_substr(char const *s, unsigned int start, size_t len); char *ft_strjoin(char const *s1, char const *s2); -char *ft_strtrim(char const *s1, char const *set); char **ft_split(char const *s, char c); char *ft_itoa(int n); -char *ft_strmapi(char const *s, char (*f)(unsigned int, char)); -void ft_striteri(char *s, void (*f)(unsigned int, char*)); -void ft_putchar_fd(char c, int fd); -void ft_putstr_fd(char *s, int fd); void ft_putendl_fd(char *s, int fd); -void ft_putnbr_fd(int n, int fd); #endif \ No newline at end of file diff --git a/incs/minishell.h b/incs/minishell.h index 0f5f032..ca5c3b5 100644 --- a/incs/minishell.h +++ b/incs/minishell.h @@ -6,27 +6,29 @@ /* By: eunwolee +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/06/29 11:05:33 by eunwolee #+# #+# */ -/* Updated: 2023/07/21 15:48:18 by eunwolee ### ########.fr */ +/* Updated: 2023/08/17 21:25:43 by eunwolee ### ########.fr */ /* */ /* ************************************************************************** */ #ifndef MINISHELL_H # define MINISHELL_H +# include # include # include +# include +# include # include +# include # include # include -# include -# include "exec.h" -# include "parse.h" # include "struct.h" +# include "init.h" +# include "parse.h" +# include "builtin.h" +# include "execute.h" # include "utils.h" # include "message.h" -# include "../Libft/libft.h" - -void init(t_data **data, char **envp); -void env_init(t_data *data, char **envp); +# include "libft.h" #endif \ No newline at end of file diff --git a/incs/parse.h b/incs/parse.h index 4e2051c..2f118a4 100644 --- a/incs/parse.h +++ b/incs/parse.h @@ -6,7 +6,7 @@ /* By: kichlee +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/07/04 07:53:54 by eunwolee #+# #+# */ -/* Updated: 2023/07/21 17:34:55 by kichlee ### ########.fr */ +/* Updated: 2023/08/19 17:00:38 by kichlee ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,18 +17,30 @@ void tokenizer(t_data *data, t_token **token, int *i); t_token *token_create(void); -void token_add_list(t_list **head, t_token **token, t_bool token_flag); +void token_add_list(t_list **head, t_token **token); void token_redirect(t_data *data, t_token *token, int *i); -void single_quote(char *input, t_token *token, int *i); -void double_quote(char *input, t_token *token, int *i, t_data *data); +void single_quote(char *input, t_token **token, int *i); +void double_quote(t_data *data, char *input, t_token **token, int *i); -void lexer(t_data *data); +t_bool lexer(t_data *data); + +t_bool expand(t_data *data, t_token **token, int *i, t_bool quote); + +/*expand_check*/ +t_bool check_heredoc(t_data *data, t_token *token, int *i); +t_bool check_question(t_data *data, t_token *token, int *i); +t_bool check_d_quote(t_data *data, t_token *token, int *i, t_bool quote); +t_bool check_other(t_data *data, t_token *token, int *i, t_bool quote); +t_bool check_special(t_data *data, t_token *token, int *i); + +/*lexer_uitls*/ +t_bool check_end(char c); +t_bool check_last_blank(char *str, int i); +void quote_utils(char *input, t_token **token, int *i); t_bool syntax(t_data *data); void parser(t_data *data); -t_bool expand(t_data *data, t_token *token, int *i, t_bool quote); - #endif \ No newline at end of file diff --git a/incs/struct.h b/incs/struct.h index d6b01ca..a6a6412 100644 --- a/incs/struct.h +++ b/incs/struct.h @@ -6,13 +6,17 @@ /* By: eunwolee +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/07/11 10:24:15 by eunwolee #+# #+# */ -/* Updated: 2023/07/16 17:37:07 by eunwolee ### ########.fr */ +/* Updated: 2023/08/17 21:25:58 by eunwolee ### ########.fr */ /* */ /* ************************************************************************** */ #ifndef STRUCT_H # define STRUCT_H +# define BUF_SIZE 1024 + +int g_error_code; + typedef enum e_bool { FALSE, @@ -30,6 +34,8 @@ typedef enum e_type T_OUTPUT, T_HEREDOC, T_APPEND, + T_SINGLE, + T_DOUBLE }t_type; typedef struct s_token @@ -37,15 +43,17 @@ typedef struct s_token int type; int redirect_type; char *str; -} t_token; + t_bool blank; + int quote; +}t_token; -//tokens와 envs에서 통용되는 리스트 구조체 typedef struct s_list { struct s_list *pre; struct s_list *next; t_token *token; char *env; + int equal_flag; }t_list; typedef struct s_leaf @@ -58,6 +66,32 @@ typedef struct s_leaf t_bool exist; }t_leaf; +typedef struct s_pid +{ + pid_t pid; + int fd[2]; +}t_pid; + +typedef struct s_pipe +{ + t_pid *com; + char **cmd_path; + char *command; + char **cmd_abs; +}t_pipe; + +typedef struct s_info +{ + int index; + int heredoc_flag; + char **heredoc_file; + int oristdin; + int oristdout; + int pipe_num; + int parent; + int pipe_index; +}t_info; + typedef struct s_data { char *input; @@ -65,7 +99,9 @@ typedef struct s_data t_list *envs; char **env_array; t_leaf *root; - int error_code; -} t_data; + t_pipe *pipe; + t_info *info; + char *abs_home; +}t_data; #endif \ No newline at end of file diff --git a/incs/utils.h b/incs/utils.h index fb9f401..f3888e7 100644 --- a/incs/utils.h +++ b/incs/utils.h @@ -6,43 +6,44 @@ /* By: kichlee +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/07/11 10:32:09 by eunwolee #+# #+# */ -/* Updated: 2023/07/21 17:34:53 by kichlee ### ########.fr */ +/* Updated: 2023/08/17 21:36:49 by kichlee ### ########.fr */ /* */ /* ************************************************************************** */ -//환경변수, 자료구조 및 기타 함수 - #ifndef UTILS_H # define UTILS_H # include "struct.h" -void env_print(t_data *data); -t_list *env_search(t_data *data, char *key); -t_bool env_remove(t_data *data, char *key); -char **env_to_array(t_data *data); - -t_list *ft_lstnew(void); -void ft_lstadd_back(t_list **lst, t_list *new); -t_list *ft_lstlast(t_list *lst); -int ft_lstsize(t_list *lst); -void ft_lstdelone(t_list *lst); -void ft_lstclear(t_list **lst); - -t_leaf *tree_create_leaf(t_leaf *parent, int leaf_type); -t_bool tree_add_left(t_leaf *parent, t_token *new_token, int leaf_type); -t_bool tree_add_right(t_leaf *parent, t_token *new_token, int leaf_type); -void tree_clear(t_leaf *leaf); - -t_bool error_back_readline(t_data *data, char *str, int error_code); -void program_error_exit(char *str); -void input_free(t_data *data); -void data_free(t_data *data); - -/*temp.c 임시 함수*/ -void tree_print(t_leaf *leaf); -void print_token(t_data *data); -void env_array_print(t_data *data); -void check_leak(void); +void error_print(char *cmd, char *option, int flag); +void check_errortype(char *str, int flag); +t_bool error_back_readline(t_data *data, \ + char *str, int error_code_b, int flag); +void program_error_exit(char *str); + +void env_print(t_data *data); +t_list *env_search(t_data *data, char *key, t_bool flag); +t_bool env_remove(t_data *data, char *key); +char **env_to_array(t_data *data); + +t_list *ft_lstnew(void); +void ft_lstadd_back(t_list **lst, t_list *new); +t_list *ft_lstlast(t_list *lst); +int ft_lstsize(t_list *lst); +void ft_lstdelone(t_list *lst); +void ft_lstclear(t_list **lst); + +t_leaf *tree_create_leaf(t_leaf *parent, int leaf_type); +t_bool tree_add_left(t_leaf *parent, t_token *new_token, int leaf_type); +t_bool tree_add_right(t_leaf *parent, t_token *new_token, int leaf_type); +void tree_clear(t_leaf *leaf); + +void input_free(t_data *data); +void data_free(t_data *data); + +void tree_print(t_leaf *leaf); +void print_token(t_data *data); +void env_array_print(t_data *data); +void check_leak(void); #endif \ No newline at end of file diff --git a/minishell b/minishell deleted file mode 100755 index a9c463e..0000000 Binary files a/minishell and /dev/null differ diff --git a/Libft/ft_calloc.c b/srcs/Libft/ft_calloc.c similarity index 91% rename from Libft/ft_calloc.c rename to srcs/Libft/ft_calloc.c index 4ab8b68..09c73f7 100644 --- a/Libft/ft_calloc.c +++ b/srcs/Libft/ft_calloc.c @@ -6,11 +6,11 @@ /* By: eunwolee +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/11/12 18:35:23 by eunwolee #+# #+# */ -/* Updated: 2022/11/15 20:29:04 by eunwolee ### ########.fr */ +/* Updated: 2023/08/17 13:32:33 by eunwolee ### ########.fr */ /* */ /* ************************************************************************** */ -#include "libft.h" +#include "../../incs/minishell.h" void *ft_calloc(size_t count, size_t size) { diff --git a/Libft/ft_isalnum.c b/srcs/Libft/ft_isalnum.c similarity index 90% rename from Libft/ft_isalnum.c rename to srcs/Libft/ft_isalnum.c index f0103f4..4f0615d 100644 --- a/Libft/ft_isalnum.c +++ b/srcs/Libft/ft_isalnum.c @@ -6,11 +6,11 @@ /* By: eunwolee +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/11/09 16:51:21 by eunwolee #+# #+# */ -/* Updated: 2022/11/14 18:26:47 by eunwolee ### ########.fr */ +/* Updated: 2023/08/17 13:32:37 by eunwolee ### ########.fr */ /* */ /* ************************************************************************** */ -#include "libft.h" +#include "../../incs/minishell.h" int ft_isalnum(int c) { diff --git a/Libft/ft_isalpha.c b/srcs/Libft/ft_isalpha.c similarity index 100% rename from Libft/ft_isalpha.c rename to srcs/Libft/ft_isalpha.c diff --git a/Libft/ft_isdigit.c b/srcs/Libft/ft_isdigit.c similarity index 100% rename from Libft/ft_isdigit.c rename to srcs/Libft/ft_isdigit.c diff --git a/Libft/ft_itoa.c b/srcs/Libft/ft_itoa.c similarity index 87% rename from Libft/ft_itoa.c rename to srcs/Libft/ft_itoa.c index 569aa48..5edabb4 100644 --- a/Libft/ft_itoa.c +++ b/srcs/Libft/ft_itoa.c @@ -6,11 +6,11 @@ /* By: eunwolee +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/11/15 12:28:06 by eunwolee #+# #+# */ -/* Updated: 2022/11/17 13:30:13 by eunwolee ### ########.fr */ +/* Updated: 2023/08/17 13:32:46 by eunwolee ### ########.fr */ /* */ /* ************************************************************************** */ -#include "libft.h" +#include "../../incs/minishell.h" static int cnt_digit(long n) { @@ -41,9 +41,9 @@ char *ft_itoa(int n) num = (long)n; size = cnt_digit(num); - dest = (char *)malloc(sizeof(char) * (size + 1)); + dest = (char *)ft_calloc((size + 1), sizeof(char)); if (!dest) - return (0); + program_error_exit("bash"); idx = size - 1; if (!num) dest[0] = '0'; diff --git a/Libft/ft_memset.c b/srcs/Libft/ft_memset.c similarity index 91% rename from Libft/ft_memset.c rename to srcs/Libft/ft_memset.c index 0959e11..da4975a 100644 --- a/Libft/ft_memset.c +++ b/srcs/Libft/ft_memset.c @@ -6,11 +6,11 @@ /* By: eunwolee +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/11/10 12:33:34 by eunwolee #+# #+# */ -/* Updated: 2022/11/14 20:27:03 by eunwolee ### ########.fr */ +/* Updated: 2023/08/17 13:32:54 by eunwolee ### ########.fr */ /* */ /* ************************************************************************** */ -#include "libft.h" +#include "../../incs/minishell.h" void *ft_memset(void *b, int c, size_t len) { diff --git a/Libft/ft_putendl_fd.c b/srcs/Libft/ft_putendl_fd.c similarity index 90% rename from Libft/ft_putendl_fd.c rename to srcs/Libft/ft_putendl_fd.c index 88597d8..6471868 100644 --- a/Libft/ft_putendl_fd.c +++ b/srcs/Libft/ft_putendl_fd.c @@ -6,11 +6,11 @@ /* By: eunwolee +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/11/16 21:45:36 by eunwolee #+# #+# */ -/* Updated: 2022/11/17 12:34:37 by eunwolee ### ########.fr */ +/* Updated: 2023/08/17 13:32:56 by eunwolee ### ########.fr */ /* */ /* ************************************************************************** */ -#include "libft.h" +#include "../../incs/minishell.h" void ft_putendl_fd(char *s, int fd) { diff --git a/Libft/ft_split.c b/srcs/Libft/ft_split.c similarity index 83% rename from Libft/ft_split.c rename to srcs/Libft/ft_split.c index 2c4a6c4..9b742e7 100644 --- a/Libft/ft_split.c +++ b/srcs/Libft/ft_split.c @@ -6,17 +6,16 @@ /* By: eunwolee +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/11/14 21:52:44 by eunwolee #+# #+# */ -/* Updated: 2023/04/22 14:58:31 by eunwolee ### ########.fr */ +/* Updated: 2023/08/17 13:33:00 by eunwolee ### ########.fr */ /* */ /* ************************************************************************** */ -#include "libft.h" +#include "../../incs/minishell.h" char **ft_split(char const *s, char c); static int cnt_str(char const *s, int c); static int exe_split(char **dest, const char *s, char c, int *idx); static int cnt_len(char const *s, char c); -static char **clear(char **dest, int idx); char **ft_split(char const *s, char c) { @@ -27,14 +26,13 @@ char **ft_split(char const *s, char c) cnt = cnt_str(s, c); dest = (char **)ft_calloc(cnt + 1, sizeof(char *)); if (!dest) - return (0); + program_error_exit("bash"); if (!cnt) dest[0] = ft_strdup(""); else { idx = 0; - if (exe_split(dest, s, c, &idx) == -1) - return (clear(dest, idx)); + exe_split(dest, s, c, &idx); } return (dest); } @@ -72,8 +70,6 @@ static int exe_split(char **dest, const char *s, char c, int *idx) { size = cnt_len(s, c); dest[*idx] = ft_substr(s, 0, size); - if (!dest[*idx]) - return (-1); s += size; *idx += 1; } @@ -90,11 +86,3 @@ static int cnt_len(char const *s, char c) len++; return (len); } - -static char **clear(char **dest, int idx) -{ - while (idx--) - free (dest[idx]); - free (dest); - return (0); -} diff --git a/Libft/ft_strdup.c b/srcs/Libft/ft_strdup.c similarity index 84% rename from Libft/ft_strdup.c rename to srcs/Libft/ft_strdup.c index 5a58a49..aed6df3 100644 --- a/Libft/ft_strdup.c +++ b/srcs/Libft/ft_strdup.c @@ -6,11 +6,11 @@ /* By: eunwolee +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/11/12 18:07:32 by eunwolee #+# #+# */ -/* Updated: 2022/12/02 15:48:12 by eunwolee ### ########.fr */ +/* Updated: 2023/08/17 13:33:05 by eunwolee ### ########.fr */ /* */ /* ************************************************************************** */ -#include "libft.h" +#include "../../incs/minishell.h" char *ft_strdup(const char *s1) { @@ -18,9 +18,9 @@ char *ft_strdup(const char *s1) char *dest; len = ft_strlen(s1); - dest = (char *)malloc(sizeof(char) * (len + 1)); + dest = (char *)ft_calloc((len + 1), sizeof(char)); if (!dest) - return (0); + program_error_exit("bash"); ft_strlcpy(dest, s1, len + 1); return (dest); } diff --git a/Libft/ft_strjoin.c b/srcs/Libft/ft_strjoin.c similarity index 83% rename from Libft/ft_strjoin.c rename to srcs/Libft/ft_strjoin.c index 1962922..b0d72d6 100644 --- a/Libft/ft_strjoin.c +++ b/srcs/Libft/ft_strjoin.c @@ -6,20 +6,20 @@ /* By: eunwolee +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/11/14 20:57:36 by eunwolee #+# #+# */ -/* Updated: 2022/11/15 15:18:15 by eunwolee ### ########.fr */ +/* Updated: 2023/08/17 13:33:08 by eunwolee ### ########.fr */ /* */ /* ************************************************************************** */ -#include "libft.h" +#include "../../incs/minishell.h" char *ft_strjoin(char const *s1, char const *s2) { int idx; char *str; - str = (char *)malloc(sizeof(char) * (ft_strlen(s1) + ft_strlen(s2) + 1)); + str = (char *)ft_calloc((ft_strlen(s1) + ft_strlen(s2) + 1), sizeof(char)); if (!str) - return (0); + program_error_exit("bash"); idx = 0; while (*s1) str[idx++] = *s1++; diff --git a/Libft/ft_strlcat.c b/srcs/Libft/ft_strlcat.c similarity index 92% rename from Libft/ft_strlcat.c rename to srcs/Libft/ft_strlcat.c index 54737c8..3332bd6 100644 --- a/Libft/ft_strlcat.c +++ b/srcs/Libft/ft_strlcat.c @@ -6,11 +6,11 @@ /* By: eunwolee +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/11/12 16:27:27 by eunwolee #+# #+# */ -/* Updated: 2022/11/14 20:29:15 by eunwolee ### ########.fr */ +/* Updated: 2023/08/17 13:33:15 by eunwolee ### ########.fr */ /* */ /* ************************************************************************** */ -#include "libft.h" +#include "../../incs/minishell.h" size_t ft_strlcat(char *dst, const char *src, size_t dstsize) { diff --git a/Libft/ft_strlcpy.c b/srcs/Libft/ft_strlcpy.c similarity index 91% rename from Libft/ft_strlcpy.c rename to srcs/Libft/ft_strlcpy.c index 4f7b7ad..e8b4992 100644 --- a/Libft/ft_strlcpy.c +++ b/srcs/Libft/ft_strlcpy.c @@ -6,11 +6,11 @@ /* By: eunwolee +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/11/12 16:08:41 by eunwolee #+# #+# */ -/* Updated: 2022/11/17 15:37:54 by eunwolee ### ########.fr */ +/* Updated: 2023/08/17 13:33:18 by eunwolee ### ########.fr */ /* */ /* ************************************************************************** */ -#include "libft.h" +#include "../../incs/minishell.h" size_t ft_strlcpy(char *dst, const char *src, size_t dstsize) { diff --git a/Libft/ft_strlen.c b/srcs/Libft/ft_strlen.c similarity index 90% rename from Libft/ft_strlen.c rename to srcs/Libft/ft_strlen.c index cc14ae3..464b0a2 100644 --- a/Libft/ft_strlen.c +++ b/srcs/Libft/ft_strlen.c @@ -6,11 +6,11 @@ /* By: eunwolee +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/11/12 15:48:24 by eunwolee #+# #+# */ -/* Updated: 2023/07/03 08:52:25 by eunwolee ### ########.fr */ +/* Updated: 2023/08/17 13:33:21 by eunwolee ### ########.fr */ /* */ /* ************************************************************************** */ -#include "libft.h" +#include "../../incs/minishell.h" size_t ft_strlen(const char *s) { diff --git a/Libft/ft_strncat.c b/srcs/Libft/ft_strncat.c similarity index 78% rename from Libft/ft_strncat.c rename to srcs/Libft/ft_strncat.c index 171eb95..7b15ddb 100644 --- a/Libft/ft_strncat.c +++ b/srcs/Libft/ft_strncat.c @@ -6,11 +6,11 @@ /* By: eunwolee +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/07/03 07:51:04 by eunwolee #+# #+# */ -/* Updated: 2023/07/21 16:20:55 by eunwolee ### ########.fr */ +/* Updated: 2023/08/17 13:33:25 by eunwolee ### ########.fr */ /* */ /* ************************************************************************** */ -#include "libft.h" +#include "../../incs/minishell.h" char *ft_strncat(char *dest, char *src, int n) { @@ -19,26 +19,24 @@ char *ft_strncat(char *dest, char *src, int n) int i; int j; + if (!dest || !src) + return (NULL); size = ft_strlen(dest) + n; res = (char *)ft_calloc(size + 1, sizeof(char)); + if (!res) + program_error_exit("bash"); i = 0; - if (dest) + while (dest[i]) { - while (dest[i]) - { - res[i] = dest[i]; - i++; - } - // free(dest); + res[i] = dest[i]; + i++; } + free(dest); j = 0; - if (src) + while (j < n) { - while (j < n) - { - res[i + j] = src[j]; - j++; - } + res[i + j] = src[j]; + j++; } return (res); } diff --git a/Libft/ft_strncmp.c b/srcs/Libft/ft_strncmp.c similarity index 92% rename from Libft/ft_strncmp.c rename to srcs/Libft/ft_strncmp.c index fedb6ba..134951d 100644 --- a/Libft/ft_strncmp.c +++ b/srcs/Libft/ft_strncmp.c @@ -6,11 +6,11 @@ /* By: eunwolee +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/11/12 17:23:49 by eunwolee #+# #+# */ -/* Updated: 2022/11/17 16:34:45 by eunwolee ### ########.fr */ +/* Updated: 2023/08/17 13:33:27 by eunwolee ### ########.fr */ /* */ /* ************************************************************************** */ -#include "libft.h" +#include "../../incs/minishell.h" int ft_strncmp(const char *s1, const char *s2, size_t n) { diff --git a/Libft/ft_substr.c b/srcs/Libft/ft_substr.c similarity index 86% rename from Libft/ft_substr.c rename to srcs/Libft/ft_substr.c index fc44b76..cfffdd9 100644 --- a/Libft/ft_substr.c +++ b/srcs/Libft/ft_substr.c @@ -6,11 +6,11 @@ /* By: eunwolee +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/11/14 17:55:14 by eunwolee #+# #+# */ -/* Updated: 2022/11/25 16:48:59 by eunwolee ### ########.fr */ +/* Updated: 2023/08/17 13:33:30 by eunwolee ### ########.fr */ /* */ /* ************************************************************************** */ -#include "libft.h" +#include "../../incs/minishell.h" char *ft_substr(char const *s, unsigned int start, size_t len) { @@ -24,9 +24,9 @@ char *ft_substr(char const *s, unsigned int start, size_t len) size = ft_strlen(s + start); else size = len; - tmp = (char *)malloc(sizeof(char) * (size + 1)); + tmp = (char *)ft_calloc((size + 1), sizeof(char)); if (!tmp) - return (0); + program_error_exit("bash"); idx = 0; if (size) while (idx < len && s[start]) diff --git a/srcs/builtin/builtin.c b/srcs/builtin/builtin.c new file mode 100644 index 0000000..d7d7c90 --- /dev/null +++ b/srcs/builtin/builtin.c @@ -0,0 +1,63 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* builtin.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: eunwolee +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/07/21 17:42:18 by eunwolee #+# #+# */ +/* Updated: 2023/08/17 20:46:11 by eunwolee ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../../incs/minishell.h" + +int check_builtin_func(char *name); +int exec_builtin(int builtnum, t_data *data); + +int check_builtin_func(char *name) +{ + if (!ft_strncmp(name, "cd", 3)) + return (1); + if (!ft_strncmp(name, "echo", 5)) + return (2); + if (!ft_strncmp(name, "exit", 5)) + return (3); + if (!ft_strncmp(name, "pwd", 4)) + return (4); + if (!ft_strncmp(name, "unset", 6)) + return (5); + if (!ft_strncmp(name, "export", 7)) + return (6); + if (!ft_strncmp(name, "env", 4)) + return (7); + return (0); +} + +int exec_builtin(int builtnum, t_data *data) +{ + if (builtnum == 1) + { + if (ft_cd(data) == FALSE) + return (1); + } + if (builtnum == 2) + ft_echo(data->root->left_child->right_child->right_child); + if (builtnum == 3) + ft_exit(data); + if (builtnum == 4) + ft_pwd(); + if (builtnum == 5) + ft_unset(data, data->root); + if (builtnum == 6) + { + if (ft_export(data, data->root->left_child->right_child) == FALSE) + return (1); + } + if (builtnum == 7) + { + if (ft_env(data) == FALSE) + return (127); + } + return (FALSE); +} diff --git a/srcs/builtin/ft_add_env_front.c b/srcs/builtin/ft_add_env_front.c new file mode 100644 index 0000000..ee9b1ac --- /dev/null +++ b/srcs/builtin/ft_add_env_front.c @@ -0,0 +1,52 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_add_env_front.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: eunwolee +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/08/14 20:38:22 by eunwolee #+# #+# */ +/* Updated: 2023/08/17 13:30:35 by eunwolee ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../../incs/minishell.h" + +void ft_add_env_front(t_data *head, char *key, char *value); +static t_list *create_env_node(char *key, char *value); +static void ft_lstadd_front(t_list **lst, t_list *new); + +void ft_add_env_front(t_data *head, char *key, char *value) +{ + if (head->envs == NULL) + head->envs = create_env_node(key, value); + else + ft_lstadd_front(&(head->envs), create_env_node(key, value)); +} + +static t_list *create_env_node(char *key, char *value) +{ + t_list *new_node; + + new_node = ft_lstnew(); + new_node->token = (t_token *)ft_calloc(1, sizeof(t_token)); + if (!new_node->token) + program_error_exit("bash"); + if (value) + { + new_node->env = ft_strncat(key, value, ft_strlen(value)); + free(value); + } + else + new_node->env = key; + return (new_node); +} + +static void ft_lstadd_front(t_list **lst, t_list *new) +{ + if (!lst || !new) + return ; + new->next = *lst; + (*lst)->pre = new; + *lst = new; +} diff --git a/srcs/builtin/ft_atolong.c b/srcs/builtin/ft_atolong.c new file mode 100644 index 0000000..2f71491 --- /dev/null +++ b/srcs/builtin/ft_atolong.c @@ -0,0 +1,75 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_atolong.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: eunwolee +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/08/10 20:31:59 by kichlee #+# #+# */ +/* Updated: 2023/08/15 18:45:35 by eunwolee ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../../incs/minishell.h" + +long long ft_atolong(char *str, int *flag); +static char *pass_blank_sign(char *str, int *sign); +static int check_overflow(long long result, char ch); +static int check_underflow(long long result, char ch); + +long long ft_atolong(char *str, int *flag) +{ + long long result; + int sign; + int i; + + result = 0; + sign = 1; + i = -1; + str = pass_blank_sign(str, &sign); + while (ft_isdigit(str[++i])) + { + if (check_overflow(result, str[i])) + { + if ((sign == 1 && check_overflow(result, str[i])) || \ + (sign == -1 && check_underflow(result, str[i]))) + { + *flag = 0; + return (0); + } + } + result = result * 10 + (str[i] - '0'); + } + *flag = 1; + return (result * sign); +} + +static char *pass_blank_sign(char *str, int *sign) +{ + while ((*str >= 9 && *str <= 13) || *str == 32) + ++str; + if (*str == '+' || *str == '-') + { + if (*str == '-') + *sign *= -1; + str++; + } + return (str); +} + +static int check_overflow(long long result, char ch) +{ + if (result > LLONG_MAX / 10 || \ + (result == LLONG_MAX / 10 && (ch - '0') > LLONG_MAX % 10)) + return (1); + return (0); +} + +static int check_underflow(long long result, char ch) +{ + if (result > (long long)(-(LLONG_MIN / 10)) || \ + (result == (long long)(-(LLONG_MIN / 10)) && (long long)(ch - '0') > \ + (long long)(-(LLONG_MIN / 10)))) + return (1); + return (0); +} diff --git a/srcs/builtin/ft_cd.c b/srcs/builtin/ft_cd.c index 565cdcf..bfedb09 100644 --- a/srcs/builtin/ft_cd.c +++ b/srcs/builtin/ft_cd.c @@ -3,56 +3,82 @@ /* ::: :::::::: */ /* ft_cd.c :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: kichlee +#+ +:+ +#+ */ +/* By: eunwolee +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ -/* Created: 2023/07/19 02:31:18 by kichan #+# #+# */ -/* Updated: 2023/07/20 22:27:49 by kichlee ### ########.fr */ +/* Created: 2023/07/19 02:31:18 by kichlee #+# #+# */ +/* Updated: 2023/08/17 13:25:23 by eunwolee ### ########.fr */ /* */ /* ************************************************************************** */ -#include "../incs/minishell.h" +#include "../../incs/minishell.h" -int change_directory(t_data *data, char *path) +t_bool ft_cd(t_data *data); +static int change_directory(t_data *data, char *path); +static int change_home(void); +static t_bool is_failuer(t_data *data, char *pwd, char *option); +static void is_success(t_data *data, char *pwd); + +t_bool ft_cd(t_data *data) +{ + char *option; + char *pwd; + + option = NULL; + pwd = (char *)ft_calloc(BUF_SIZE, sizeof(char)); + if (!pwd) + program_error_exit("bash"); + if (!(data->root->left_child->right_child->right_child)) + { + change_directory(data, "HOME"); + free(pwd); + } + else if (change_directory(data, \ + data->root->left_child->right_child->right_child->token->str) != 0) + return (is_failuer(data, pwd, option)); + else + is_success(data, pwd); + return (TRUE); +} + +static int change_directory(t_data *data, char *path) { char *buf; int res; - char pwd[1024]; - - printf("\npath : %s\n", path); - if (!ft_strncmp(path, "~", 1)) - buf = ft_strdup(env_search(data, "HOME")->env + 5); - else if (!ft_strncmp(path, "-", 1)) - buf = ft_strdup(env_search(data, "OLDPWD")->env + 7); + char pwd[BUF_SIZE]; + + if (!ft_strncmp(path, "HOME", 5)) + { + if (env_search(data, "HOME", TRUE) == NULL) + return (change_home()); + else + buf = ft_strdup(env_search(data, "HOME", TRUE)->env + 5); + } else buf = ft_strdup(path); - if (!buf) - exit(1); - printf("buf val : %s\n", buf); res = chdir(buf); - getcwd(pwd, 1024); - printf("current directory : %s\n",pwd); - free(buf); + getcwd(pwd, BUF_SIZE); + free(buf); return (res); } -void ft_cd(t_data *data) +static int change_home(void) { - char *option; - char pwd[1024]; - option = NULL; - - if(!(data->root->left_child->right_child->right_child)) - change_directory(data, "~"); - else if(change_directory(data,data->root->left_child->right_child->right_child->token->str) != 0) - { - option = data->root->left_child->right_child->right_child->token->str; - printf("bash: %s: No such file or directory\n", option); - } - else - { - getcwd(pwd, 1024); - printf("current directory : %s\n",pwd); - update_env(data, "OLDPWD", env_search(data, "PWD")->env); - update_env(data, "PWD", pwd); - } -} \ No newline at end of file + printf("bash: cd: HOME not set\n"); + return (-1); +} + +static t_bool is_failuer(t_data *data, char *pwd, char *option) +{ + option = data->root->left_child->right_child->right_child->token->str; + printf("bash: %s: No such file or directory\n", option); + free(pwd); + return (FALSE); +} + +static void is_success(t_data *data, char *pwd) +{ + getcwd(pwd, BUF_SIZE); + ft_update_env_cd(data, ft_strdup("OLDPWD"), \ + ft_strdup(env_search(data, "PWD", TRUE)->env + 4)); + ft_update_env_cd(data, ft_strdup("PWD"), pwd); +} diff --git a/Libft/ft_striteri.c b/srcs/builtin/ft_cnt_args.c similarity index 64% rename from Libft/ft_striteri.c rename to srcs/builtin/ft_cnt_args.c index 60e94c4..60883be 100644 --- a/Libft/ft_striteri.c +++ b/srcs/builtin/ft_cnt_args.c @@ -1,23 +1,28 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* ft_striteri.c :+: :+: :+: */ +/* ft_cnt_args.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: eunwolee +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ -/* Created: 2022/11/15 15:01:23 by eunwolee #+# #+# */ -/* Updated: 2022/11/17 14:44:32 by eunwolee ### ########.fr */ +/* Created: 2023/07/22 13:20:41 by eunwolee #+# #+# */ +/* Updated: 2023/08/14 20:49:20 by eunwolee ### ########.fr */ /* */ /* ************************************************************************** */ -void ft_striteri(char *s, void (*f)(unsigned int, char*)) +#include "../../incs/minishell.h" + +int ft_cnt_args(char **args); + +int ft_cnt_args(char **args) { - int idx; + int count; - idx = 0; - while (s[idx]) + count = 0; + while (*args != NULL) { - f(idx, &s[idx]); - idx++; + count++; + args++; } + return (count); } diff --git a/srcs/builtin/ft_echo.c b/srcs/builtin/ft_echo.c index c0605a8..30a3412 100644 --- a/srcs/builtin/ft_echo.c +++ b/srcs/builtin/ft_echo.c @@ -3,99 +3,67 @@ /* ::: :::::::: */ /* ft_echo.c :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: kichlee +#+ +:+ +#+ */ +/* By: eunwolee +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/07/19 02:30:59 by kichan #+# #+# */ -/* Updated: 2023/07/20 22:20:42 by kichlee ### ########.fr */ +/* Updated: 2023/08/16 18:06:21 by eunwolee ### ########.fr */ /* */ /* ************************************************************************** */ -#include "../incs/minishell.h" +#include "../../incs/minishell.h" +void ft_echo(t_leaf *arg); +static void check_flag(t_leaf *arg, int *cnt, int *flag); +static void print_line(t_leaf *arg); -char **join_cmd(t_leaf * com_leaf) +void ft_echo(t_leaf *arg) { - int cnt =1; + int cnt; + int flag; - t_leaf *temp = com_leaf; - t_leaf *leaf = com_leaf; - // printf("%s\n",leaf->token->str); - while(temp && temp->right_child) + cnt = 0; + flag = FALSE; + check_flag(arg, &cnt, &flag); + while (cnt--) + arg = arg->right_child; + while (arg) { - temp= temp->right_child; - cnt++; + print_line(arg); + if (arg->token->blank == TRUE && arg->right_child) + printf(" "); + arg = arg->right_child; } - char **str = (char **)ft_calloc(cnt + 1, sizeof(char *)); - - int i=1; - str[0]= leaf->token->str; - while(leaf) - { - if (leaf->right_child) - { - str[i] = leaf->right_child->token->str; - leaf = leaf->right_child; - i++; - } - else - break; - } - return str; + if (flag == FALSE) + printf("\n"); } -void check_echo_flag(char **av, int *i, int *flag) +static void check_flag(t_leaf *arg, int *cnt, int *flag) { - int j; + int i; - *i = 1; - if (av[1] && av[*i][0] == '-' && av[*i][1] == 'n') + while (arg && arg->token->str[0] == '-' && arg->token->str[1] == 'n') { - while (av[*i][0] == '-' && av[*i][1] == 'n') + i = 1; + while (arg->token->str[i] != '\0') { - j = 1; - while (av[1][j] != '\0') - { - if (av[1][j] != 'n') - return ; - j++; - } - (*i)++; + if (arg->token->str[i] != 'n') + return ; + i++; } - *flag = 1; + arg = arg->right_child; + *cnt += 1; + *flag = TRUE; } } -int count_args(char **args) -{ - int count = 0; - - while (*args != NULL) - { - count++; - args++; - } - return count; -} -void ft_echo(t_data *data) +static void print_line(t_leaf *arg) { - char **cmd; - int cnt; - int flag = 0; - // int i = 0; - int blank = 0; - cmd = join_cmd(data->root->left_child->right_child); - int k = 1; - check_echo_flag(cmd, &cnt, &flag); - blank = count_args(cmd); - if(flag == 1) - k = 2; - while (cmd[k]) + int i; + + i = 0; + while (arg->token->str[i]) { - printf("%s", cmd[k]); - if(k < blank - 1) - printf(" "); - ++k; + printf("%c", arg->token->str[i]); + i++; } - if(flag == 1) - printf("\n"); -} \ No newline at end of file +} diff --git a/srcs/builtin/ft_env.c b/srcs/builtin/ft_env.c new file mode 100644 index 0000000..902f822 --- /dev/null +++ b/srcs/builtin/ft_env.c @@ -0,0 +1,33 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_env.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: kichlee +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/07/21 19:15:04 by kichlee #+# #+# */ +/* Updated: 2023/08/07 14:49:51 by kichlee ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../../incs/minishell.h" + +t_bool ft_env(t_data *data); + +t_bool ft_env(t_data *data) +{ + char **cmd; + int arg_cnt; + + cmd = ft_join_cmd(data->root->left_child->right_child); + arg_cnt = ft_cnt_args(cmd); + if (arg_cnt != 1) + { + printf("env: %s: No such file or directory\n", cmd[1]); + free_d_char_ptr(cmd); + return (FALSE); + } + free_d_char_ptr(cmd); + env_print(data); + return (TRUE); +} diff --git a/srcs/builtin/ft_exit.c b/srcs/builtin/ft_exit.c index f18bc51..73f7ac6 100644 --- a/srcs/builtin/ft_exit.c +++ b/srcs/builtin/ft_exit.c @@ -3,110 +3,107 @@ /* ::: :::::::: */ /* ft_exit.c :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: kichan +#+ +:+ +#+ */ +/* By: eunwolee +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ -/* Created: 2023/07/19 16:23:29 by kichan #+# #+# */ -/* Updated: 2023/07/19 21:50:38 by kichan ### ########.fr */ +/* Created: 2023/07/19 16:23:29 by kichlee #+# #+# */ +/* Updated: 2023/08/17 21:31:22 by eunwolee ### ########.fr */ /* */ /* ************************************************************************** */ -#include "../incs/minishell.h" +#include "../../incs/minishell.h" -int is_num_str(char *str) +void ft_exit(t_data *data); +static void arg_over_one(t_data *data, int count, char **cmd, int flag); +static void arg_over_two(t_data *data, int count, char **cmd, int flag); +static void exit_not_num(t_data *data, char *str); +static int is_num_str(char *str); + +void ft_exit(t_data *data) { - int i; + long long status; + char **cmd; + int count; + int flag; - i = 0; - if (str[0] == '-' || str[0] == '+') - i++; - while (str[i]) + cmd = ft_join_cmd(data->root->left_child->right_child); + count = ft_cnt_args(cmd); + flag = 1; + status = 0; + if (count == 1) { - if (!('0' <= str[i] && str[i] <= '9')) - return (0); - i++; + printf("exit\n"); + exit(status); } - return (1); -} - -void exit_not_num(t_data *data) -{ - printf("exit\n"); - printf("bash: exit: %s: numeric argument required\n", data->root->left_child->right_child->token->str); - exit(255); -} - -int count_args_two(char **args) -{ - int count = 0; - - while (*args != NULL) - { - count++; - args++; - } - - return count; + else + arg_over_one(data, count, cmd, flag); + free_d_char_ptr(cmd); } -char **join_cmd_two(t_leaf * com_leaf) +static void arg_over_one(t_data *data, int count, char **cmd, int flag) { - int cnt =1; + int status; - t_leaf *temp = com_leaf; - t_leaf *leaf = com_leaf; - // printf("%s\n",leaf->token->str); - while(temp && temp->right_child) + if (count == 2) { - temp= temp->right_child; - cnt++; + if (!ft_strncmp("-9223372036854775808", cmd[1], 20)) + { + printf("exit\n"); + g_error_code = 0; + exit(0); + } + status = ft_atolong(cmd[1], &flag); + if (flag && is_num_str(cmd[1]) && ft_strlen(cmd[1]) <= 20) + { + printf("exit\n"); + g_error_code = status % 256; + exit(status % 256); + } + exit_not_num(data, cmd[1]); } - char **str = (char **)ft_calloc(cnt + 1, sizeof(char *)); - - int i=1; - str[0]= leaf->token->str; - while(leaf) - { - if (leaf->right_child) - { - str[i] = leaf->right_child->token->str; - leaf = leaf->right_child; - i++; - } - else - break; - } - return str; + else + arg_over_two(data, count, cmd, flag); } - -void ft_exit(t_data *data) +static void arg_over_two(t_data *data, int count, char **cmd, int flag) { - int status; - char **cmd; - int count; - - cmd = join_cmd_two(data->root->left_child->right_child); - count = count_args_two(cmd); - status = 0; - if (count == 1) - { - printf("exit\n"); - exit(status); - } - else if (count == 2) + int i; + + i = 1; + ft_atolong(cmd[1], &flag); + while (i < count) { - if (is_num_str(cmd[1])) + if (flag && is_num_str(cmd[i]) && ft_strlen(cmd[i]) <= 20) { - status = ft_atoi(cmd[1]); - printf("exit\n"); - exit(status); + check_errortype("error", 3); + g_error_code = 1; + break ; } else - exit_not_num(data); + exit_not_num(data, cmd[i]); + ++i; } - else +} + +static void exit_not_num(t_data *data, char *str) +{ + (void) data; + check_errortype(str, 4); + g_error_code = 255; + exit(255); +} + +static int is_num_str(char *str) +{ + int i; + + i = 0; + if (str[0] == '-' || str[0] == '+') + i++; + while (str[i]) { - printf("bash: exit: too many arguments\n"); - status = 1; + if (!('0' <= str[i] && str[i] <= '9')) + return (0); + i++; } + return (1); } diff --git a/srcs/builtin/ft_export.c b/srcs/builtin/ft_export.c index bf44036..838deab 100644 --- a/srcs/builtin/ft_export.c +++ b/srcs/builtin/ft_export.c @@ -5,236 +5,82 @@ /* +:+ +:+ +:+ */ /* By: eunwolee +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ -/* Created: 2023/07/19 16:25:07 by kichan #+# #+# */ -/* Updated: 2023/07/21 15:53:13 by eunwolee ### ########.fr */ +/* Created: 2023/08/14 11:50:55 by kichlee #+# #+# */ +/* Updated: 2023/08/17 21:14:11 by eunwolee ### ########.fr */ /* */ /* ************************************************************************** */ -#include "../incs/minishell.h" +#include "../../incs/minishell.h" -t_list *create_env_node(char *key, char *value) -{ - printf("\ncreate env_node start!\n"); - t_list *new_node = (t_list *)malloc(sizeof(t_list)); - char *key_equal; - - if (!new_node) - return NULL; - - new_node->pre = NULL; - new_node->next = NULL; - new_node->token = (t_token *)malloc(sizeof(t_token)); - if (!new_node->token) - { - free(new_node); - return NULL; - } - new_node->token->type = T_CMD; // 환경 변수는 T_CMD로 설정 - new_node->token->redirect_type = 0; // 환경 변수의 리다이렉션 타입은 0으로 설정 - new_node->token->str = key; // key 값을 환경 변수 노드의 token의 str에 할당 - key_equal = (char *)ft_calloc(sizeof(char), ft_strlen(key) + 2); - key_equal = ft_strdup(key); - key_equal[ft_strlen(key)] = '='; - key_equal[ft_strlen(key) + 1] = '\0'; - printf("\n===========keyequl=======%s\n", key_equal); - new_node->env = ft_strjoin(key_equal, value); - - return new_node; -} - -void add_env_back(t_data *head, char *key, char *value) -{ - if (head->envs == NULL) - { - printf("\nenv dose not exit!\n"); - head->envs = create_env_node(key, value); - } - else - { - printf("\nenv exit!\n"); - ft_lstadd_back(&(head->envs), create_env_node(key, value)); - } -} - -void update_env(t_data *data, char *key, char *value) -{ - t_list *tmp; - char *key_equal; - tmp = env_search(data, key); - if (!tmp) - { - add_env_back(data, key, value); - } - else - { - free(tmp->env); - key_equal = (char *)ft_calloc(sizeof(char), ft_strlen(key) + 2); - key_equal = ft_strdup(key); - key_equal[ft_strlen(key)] = '='; - key_equal[ft_strlen(key) + 1] = '\0'; - tmp->env = ft_strjoin(key_equal, value); - } -} +t_bool ft_export(t_data *data, t_leaf *arg); +static int cnt_args(t_leaf *tmp); +static void join_str(t_leaf **cur, char **tmp); +static t_bool start_export(t_data *data, char *tmp); -int check_underbar(char ch) +t_bool ft_export(t_data *data, t_leaf *cmd) { - if (ch == '_') - return (1); - return (0); + int args_cnt; + char *tmp; + + args_cnt = cnt_args(cmd->right_child); + if (!cmd || args_cnt == 0) + { + print_export_order(data); + return (TRUE); + } + cmd = cmd->right_child; + while (args_cnt--) + { + join_str(&cmd, &tmp); + if (start_export(data, tmp) == FALSE) + return (FALSE); + } + update_env_double_char(data); + return (TRUE); } -int check_name(char *str) +static void join_str(t_leaf **cur, char **tmp) { - int i; - - i = 0; - while (str[i] && str[i] != '=') - { - if (str[i] != '_' && ft_isalnum(str[i])) - return (0); - ++i; - } - return (1); + *tmp = ft_strdup((*cur)->token->str); + while (!(*cur)->token->blank && (*cur)->right_child) + { + *cur = (*cur)->right_child; + *tmp = ft_strncat(*tmp, (*cur)->token->str, \ + ft_strlen((*cur)->token->str)); + } + *cur = (*cur)->right_child; } -/** - * @brief bash 환경변수 명명 규칙 - * - * 변수 이름은 문자 (a-z, A-Z) 또는 밑줄(_)로 시작해야 합니다. - 첫 문자 이후에는 문자, 숫자 (0-9), 또는 밑줄(_)을 포함할 수 있습니다. - 변수 이름은 대소문자를 구분합니다. 예를 들어, MY_VAR와 my_var는 서로 다른 변수로 간주됩니다. - 변수 이름에 공백이나 특수 문자 (예: !, @, #, $ 등)는 사용할 수 없습니다. - 환경 변수 이름의 길이에는 제한이 있으며, 일반적으로 많은 시스템에서는 최대 길이가 있습니다. - * - */ -// int split_export(char *str, t_data *data) -// { -// int key_len; -// int value_len; -// char *key; -// char *value; -// key_len = 0; -// value_len = 0; -// while(str[key_len] != '=') -// ++key_len; -// key = (char *)ft_calloc(sizeof(char), key_len + 1); -// if(!key) -// { -// perror("ft_calloc error!"); -// exit(1); -// } -// value_len = ft_strlen(str) - key_len; -// value = (char *)ft_calloc(sizeof(char), value_len + 1); -// if(!value) -// { -// perror("ft_calloc error!"); -// exit(1); -// } -// return (0); -// } -void ft_export(t_data *data) +static int cnt_args(t_leaf *tmp) { - char **cmd; - char **tmp; - int arg_count; - int i; - - i = 1; - cmd = join_cmd(data->root->left_child->right_child); - arg_count = count_args(cmd); - - printf("arg_count : %d\n", arg_count); - if (arg_count == 1) - print_export_order(data); - else - { - while (i < arg_count) - { - printf("\nft_export while loop start!\n"); - if (!ft_isalpha(cmd[1][0]) && !check_underbar(cmd[1][0]) && !check_name(cmd[i])) - printf("bash: export: `%s': not a valid identifier\n", cmd[i]); - else if (!ft_strchr(cmd[i], '=')) // = 가 없는 경우 - { - ++i; - continue; - } - else - { - tmp = ft_split(cmd[i], '='); - update_env(data, tmp[0], tmp[1]); - free(tmp); - } - ++i; - } - } + int args; + + args = 0; + while (tmp) + { + if (tmp->token && tmp->token->type == T_ARG && tmp->token->blank == 1) + ++args; + if (!tmp->right_child && tmp->token->blank == 0) + ++args; + tmp = tmp->right_child; + } + return (args); } -char **sort_bubble(char **str, int size) +static t_bool start_export(t_data *data, char *tmp) { - char **res = (char **)ft_calloc(sizeof(char *), (size + 1)); - int sorted = 0; - int i = 0; - char *tmp; - tmp = NULL; - if (!res) - { - perror("Memory allocation error!"); - exit(1); - } - while (str[i]) - { - res[i] = ft_strdup(str[i]); - if (!res[i]) - { - perror("Memory allocation error!"); - exit(1); - } - ++i; - } - res[i] = NULL; - - while (!sorted) - { - sorted = 1; - i = 0; - while (res[i + 1]) - { - if (ft_strncmp(res[i], res[i + 1], ft_strlen(res[i])) > 0) - { - tmp = res[i]; - res[i] = res[i + 1]; - res[i + 1] = tmp; - sorted = 0; - } - ++i; - } - } - return res; + char *str1; + char *str2; + + if (check_equal(tmp) == TRUE) + { + devide_equal(tmp, &str1, &str2, TRUE); + free(tmp); + if (check_env(data, str1, str2) == FALSE) + return (FALSE); + } + else + if (check_env(data, tmp, NULL) == FALSE) + return (FALSE); + return (TRUE); } - -void print_export_order(t_data *data) -{ - int i; - int lst_size; - char **order_set; - char **order_copy; - t_list *cur; - - i = 0; - lst_size = ft_lstsize(data->envs); - cur = data->envs; - order_copy = (char **)ft_calloc(sizeof(char *), lst_size + 1); - while (cur) - { - order_copy[i] = ft_strdup(cur->env); - cur = cur->next; - ++i; - } - order_set = sort_bubble(order_copy, lst_size); - int j = 0; - while (order_set[j]) - { - printf("%s\n", order_set[j]); - ++j; - } -} \ No newline at end of file diff --git a/srcs/builtin/ft_export_check.c b/srcs/builtin/ft_export_check.c new file mode 100644 index 0000000..f922502 --- /dev/null +++ b/srcs/builtin/ft_export_check.c @@ -0,0 +1,103 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_export_check.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: eunwolee +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/08/14 21:42:23 by eunwolee #+# #+# */ +/* Updated: 2023/08/17 21:31:33 by eunwolee ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../../incs/minishell.h" + +t_bool check_env(t_data *data, char *key, char *value); +int check_plus(char *str); +int check_equal(char *str); +int check_name(char *str); +int check_underbar(char ch); + +t_bool check_env(t_data *data, char *key, char *value) +{ + if (!key) + program_error_exit("bash"); + if (!check_name(key)) + { + if (value) + printf("bash: export: '%s%s': not a valid identifier\n", key, value); + else + printf("bash: export: '%s': not a valid identifier\n", key); + g_error_code = 1; + free(key); + if (value) + free(value); + return (FALSE); + } + ft_update_env_export(data, key, value); + return (TRUE); +} + +int check_plus(char *str) +{ + int i; + + i = 0; + while (str[i]) + { + if (str[i] == '+') + return (1); + i++; + } + return (0); +} + +int check_equal(char *str) +{ + int i; + + i = 0; + while (str[i]) + { + if (str[i] == '=') + return (1); + ++i; + } + return (0); +} + +int check_name(char *str) +{ + int i; + int j; + int plus; + + j = 0; + i = 0; + plus = 0; + if (str[0] != '_' && ft_isalpha(str[0]) != 1) + return (0); + while (str[j] && str[j] != '+') + ++j; + if (str[j] == '+') + if (str[j + 1] != '=') + return (0); + plus = 0; + while (str[i] && str[i] != '=') + { + if (str[i] == '+') + ++plus; + if ((str[i] != '+' && str[i] != '_' && !ft_isalnum(str[i])) \ + || plus > 1) + return (0); + ++i; + } + return (1); +} + +int check_underbar(char ch) +{ + if (ch == '_') + return (1); + return (0); +} diff --git a/srcs/builtin/ft_export_print.c b/srcs/builtin/ft_export_print.c new file mode 100644 index 0000000..d08e19c --- /dev/null +++ b/srcs/builtin/ft_export_print.c @@ -0,0 +1,124 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_export_print.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: eunwolee +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/08/15 18:48:19 by eunwolee #+# #+# */ +/* Updated: 2023/08/17 13:29:26 by eunwolee ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../../incs/minishell.h" + +void print_export_order(t_data *data); +void devide_equal(char *src, char **str1, char **str2, \ + t_bool key_need_equal); +void free_d_char_ptr(char **str); +static char **sort_bubble(char **str); +static void print_export_quote(char **order_set); + +void print_export_order(t_data *data) +{ + int i; + char **order_set; + char **order_copy; + t_list *cur; + + i = 0; + cur = data->envs; + order_copy = (char **)ft_calloc(ft_lstsize(data->envs) + 1, sizeof(char *)); + if (!order_copy) + program_error_exit("bash"); + while (cur) + { + order_copy[i] = ft_strdup(cur->env); + cur = cur->next; + ++i; + } + order_set = sort_bubble(order_copy); + print_export_quote(order_set); + free_d_char_ptr(order_set); +} + +void devide_equal(char *src, char **str1, char **str2, t_bool key_need_equal) +{ + int equal_len; + int value_len; + + equal_len = 0; + while (src[equal_len] != '=') + equal_len++; + equal_len++; + value_len = ft_strlen(&src[equal_len]); + if (key_need_equal == TRUE) + *str1 = ft_substr(src, 0, equal_len); + else + *str1 = ft_substr(src, 0, equal_len - 1); + *str2 = ft_substr(src, equal_len, value_len); +} + +void free_d_char_ptr(char **str) +{ + int i; + + i = -1; + while (str[++i]) + free(str[i]); + free(str); +} + +static char **sort_bubble(char **str) +{ + int i; + char *tmp; + int sorted; + + i = 0; + sorted = 0; + while (!sorted) + { + sorted = 1; + i = -1; + while (str[++i + 1]) + { + if (ft_strncmp(str[i], str[i + 1], ft_strlen(str[i])) > 0) + { + tmp = str[i]; + str[i] = str[i + 1]; + str[i + 1] = tmp; + sorted = 0; + } + } + } + return (str); +} + +static void print_export_quote(char **order_set) +{ + int i; + char *str1; + char *str2; + t_bool flag; + + i = 0; + while (order_set[i]) + { + flag = check_equal(order_set[i]); + devide_equal(order_set[i], &str1, &str2, FALSE); + printf("declare -x "); + if (flag == TRUE) + { + if (!str2) + printf("%s=\"\"\n", str1); + else + printf("%s=\"%s\"\n", str1, str2); + } + else + printf("%s\n", str1); + free(str1); + free(str2); + ++i; + } +} diff --git a/srcs/builtin/ft_join_cmd.c b/srcs/builtin/ft_join_cmd.c new file mode 100644 index 0000000..e847a9e --- /dev/null +++ b/srcs/builtin/ft_join_cmd.c @@ -0,0 +1,109 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_join_cmd.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: eunwolee +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/08/14 22:15:42 by eunwolee #+# #+# */ +/* Updated: 2023/08/17 12:32:30 by eunwolee ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../../incs/minishell.h" + +char **ft_join_cmd(t_leaf *leaf); +static int get_str_cnt(t_leaf *leaf); +static int get_blank_in_str(char *str); +static char **input_leaf(t_leaf *leaf, char **input); +static void devide_str(char **str, char *tmp, int *i); + +char **ft_join_cmd(t_leaf *leaf) +{ + int cnt_str; + char **str; + + cnt_str = get_str_cnt(leaf); + str = (char **)ft_calloc(cnt_str + 1, sizeof(char *)); + if (!str) + program_error_exit("bash"); + str = input_leaf(leaf, str); + return (str); +} + +static int get_str_cnt(t_leaf *leaf) +{ + int cnt; + + cnt = 0; + while (leaf) + { + if (!leaf->token->quote) + cnt += get_blank_in_str(leaf->token->str); + cnt++; + leaf = leaf->right_child; + } + return (cnt); +} + +static int get_blank_in_str(char *str) +{ + int i; + int cnt; + + i = 0; + cnt = 0; + while (str[i]) + { + if (str[i] == ' ' || str[i] == '\t') + cnt++; + i++; + } + return (cnt); +} + +static char **input_leaf(t_leaf *leaf, char **str) +{ + int i; + char *tmp; + + i = 0; + while (leaf) + { + tmp = ft_strdup(leaf->token->str); + while (leaf->token->blank == FALSE && leaf->right_child) + { + leaf = leaf->right_child; + tmp = ft_strncat(tmp, leaf->token->str, \ + ft_strlen(leaf->token->str)); + } + if (!leaf->token->quote) + { + devide_str(str, tmp, &i); + free(tmp); + } + else + str[i++] = tmp; + leaf = leaf->right_child; + } + return (str); +} + +static void devide_str(char **str, char *tmp, int *i) +{ + int pre_blank; + int next_blank; + int cnt; + + cnt = get_blank_in_str(tmp) + 1; + pre_blank = 0; + next_blank = 0; + while (cnt--) + { + while (check_end(tmp[next_blank]) == FALSE) + next_blank++; + str[*i] = ft_substr(tmp, pre_blank, next_blank - pre_blank); + *i += 1; + pre_blank = next_blank + 1; + } +} diff --git a/srcs/builtin/ft_pwd.c b/srcs/builtin/ft_pwd.c index 943c7af..16feaf6 100644 --- a/srcs/builtin/ft_pwd.c +++ b/srcs/builtin/ft_pwd.c @@ -3,44 +3,38 @@ /* ::: :::::::: */ /* ft_pwd.c :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: kichan +#+ +:+ +#+ */ +/* By: eunwolee +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ -/* Created: 2023/07/19 16:24:31 by kichan #+# #+# */ -/* Updated: 2023/07/20 00:31:25 by kichan ### ########.fr */ +/* Created: 2023/07/19 16:24:31 by kichlee #+# #+# */ +/* Updated: 2023/08/17 12:02:00 by eunwolee ### ########.fr */ /* */ /* ************************************************************************** */ -#define BUF_SIZE 1024 -#include "../incs/minishell.h" +#include "../../incs/minishell.h" -void ft_pwd() +void ft_pwd(void); + +void ft_pwd(void) { - char *buf; - size_t buf_size; + char *buf; + size_t buf_size; - buf = NULL; - buf_size = BUF_SIZE; - while (1) - { - buf = (char *)ft_calloc(buf_size, sizeof(char)); - if(!buf) - { - perror("ft_calloc fail!"); - // malloc 실패시에 프로그램 종료 - exit(1); - } - if(getcwd(buf, buf_size) != NULL) - { - printf("%s\n", buf); - free(buf); - return ; - } - free(buf); - if(errno != ERANGE) - { - perror("getcwd error!"); - exit(1); - } - buf_size *= 2; - } + buf = NULL; + buf_size = BUF_SIZE; + while (1) + { + buf = (char *)ft_calloc(buf_size, sizeof(char)); + if (!buf) + program_error_exit("bash"); + if (getcwd(buf, buf_size) != NULL) + { + printf("%s\n", buf); + free(buf); + return ; + } + free(buf); + if (buf_size > SIZE_MAX / 2) + program_error_exit("bash"); + buf_size *= 2; + } } diff --git a/srcs/builtin/ft_test.c b/srcs/builtin/ft_test.c deleted file mode 100644 index 9795ba7..0000000 --- a/srcs/builtin/ft_test.c +++ /dev/null @@ -1,72 +0,0 @@ -// #include -// #include -// #include - -// char **sort_bubble(char **str) -// { -// char **res = (char **)malloc(sizeof(char *) * (5 + 1)); // 마지막에 NULL 포인터를 위해 추가 공간 할당 -// if (!res) -// { -// perror("Memory allocation error!"); -// exit(1); -// } - -// // 입력된 문자열 포인터 배열을 결과 배열에 복사합니다. -// int i = 0; -// while (str[i]) -// { -// printf("while loop start!\n"); -// printf("str[i] : %s\n", str[i]); -// res[i] = strdup(str[i]); -// if (!res[i]) -// { -// perror("Memory allocation error!"); -// exit(1); -// } -// ++i; -// } -// res[i] = NULL; - -// int sorted = 0; -// while (!sorted) -// { -// sorted = 1; -// i = 0; -// while (res[i + 1]) -// { -// if (strcmp(res[i], res[i + 1]) > 0) -// { -// char *tmp = res[i]; -// res[i] = res[i + 1]; -// res[i + 1] = tmp; -// sorted = 0; -// } -// ++i; -// } -// } - -// return res; -// } - -// int main() -// { -// char **str; -// char **res; -// int i = 0; - - -// str[0] = "abc"; -// str[1] = "bbc"; -// str[2] = "cba"; -// str[3] = "aabcd"; -// str[4] = "sdfb"; -// str[5] = NULL; -// res = sort_bubble(str); - -// while (res[i]) -// { -// printf("%s\n", res[i]); -// ++i; -// } -// return (0); -// } \ No newline at end of file diff --git a/srcs/builtin/ft_unset.c b/srcs/builtin/ft_unset.c index 1cdc259..5ca9ab2 100644 --- a/srcs/builtin/ft_unset.c +++ b/srcs/builtin/ft_unset.c @@ -3,50 +3,38 @@ /* ::: :::::::: */ /* ft_unset.c :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: kichan +#+ +:+ +#+ */ +/* By: eunwolee +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ -/* Created: 2023/07/19 22:51:02 by kichan #+# #+# */ -/* Updated: 2023/07/19 23:56:22 by kichan ### ########.fr */ +/* Created: 2023/07/19 22:51:02 by kichlee #+# #+# */ +/* Updated: 2023/08/17 12:40:22 by eunwolee ### ########.fr */ /* */ /* ************************************************************************** */ -#include "../incs/minishell.h" +#include "../../incs/minishell.h" -void env_clear(t_data *data) +void ft_unset(t_data *data, t_leaf *cur_root); +void update_env_double_char(t_data *data); + +void ft_unset(t_data *data, t_leaf *cur_root) { - printf("env clear start!\n"); - t_list *current = data->envs; - while (current != NULL) + char **cmd; + int arg_cnt; + int i; + + cmd = ft_join_cmd(cur_root->left_child->right_child); + arg_cnt = ft_cnt_args(cmd); + i = 1; + while (i < arg_cnt) { - t_list *next = current->next; - ft_lstdelone(current); - current = next; + env_remove(data, cmd[i]); + ++i; } - data->envs = NULL; + free_d_char_ptr(cmd); + update_env_double_char(data); } -void ft_unset(t_data *data) +void update_env_double_char(t_data *data) { - char **cmd; - int arg_cnt; - int i; - - cmd = join_cmd(data->root->left_child->right_child); - arg_cnt = count_args(cmd) - 1; - i = 1; - printf("\n=====arg_Cnt : %d\n========", arg_cnt); - if(arg_cnt == 0) - { - printf("if start!"); - env_clear(data); - } - else - { - printf("else start!"); - while (i < arg_cnt) - { - env_remove(data, cmd[i]); - ++i; - } - } -} \ No newline at end of file + free(data->env_array); + data->env_array = env_to_array(data); +} diff --git a/Libft/ft_memchr.c b/srcs/builtin/ft_update_env_cd.c similarity index 51% rename from Libft/ft_memchr.c rename to srcs/builtin/ft_update_env_cd.c index ed5928a..a3f920a 100644 --- a/Libft/ft_memchr.c +++ b/srcs/builtin/ft_update_env_cd.c @@ -1,29 +1,35 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* ft_memchr.c :+: :+: :+: */ +/* ft_update_env_cd.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: eunwolee +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ -/* Created: 2022/11/11 15:44:27 by eunwolee #+# #+# */ -/* Updated: 2022/11/14 20:26:04 by eunwolee ### ########.fr */ +/* Created: 2023/08/15 23:24:39 by eunwolee #+# #+# */ +/* Updated: 2023/08/16 15:54:47 by eunwolee ### ########.fr */ /* */ /* ************************************************************************** */ -#include "libft.h" +#include "../../incs/minishell.h" -void *ft_memchr(const void *s, int c, size_t n) +void ft_update_env_cd(t_data *data, char *key, char *value); + +void ft_update_env_cd(t_data *data, char *key, char *value) { - const unsigned char *str; - unsigned char ch; + t_list *tmp; - str = (const unsigned char *)s; - ch = (unsigned char)c; - while (n--) + if (!key || !value) + program_error_exit("bash"); + tmp = env_search(data, key, TRUE); + if (!tmp) + ft_add_env_front(data, key, value); + else { - if (*str == ch) - return ((void *)str); - str++; + free(tmp->env); + tmp->env = ft_strdup(key); + tmp->env = ft_strncat(tmp->env, "=", 1); + tmp->env = ft_strncat(tmp->env, value, ft_strlen(value)); + free(key); + free(value); } - return (0); } diff --git a/srcs/builtin/ft_update_env_export.c b/srcs/builtin/ft_update_env_export.c new file mode 100644 index 0000000..22ab513 --- /dev/null +++ b/srcs/builtin/ft_update_env_export.c @@ -0,0 +1,117 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_update_env_export.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: eunwolee +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/08/15 00:37:38 by eunwolee #+# #+# */ +/* Updated: 2023/08/17 10:57:04 by eunwolee ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../../incs/minishell.h" + +void ft_update_env_export(t_data *data, char *key, char *value); +static char *get_tmp_key(char *key, t_bool plus); +static void is_not_plus(t_data *data, \ + char *key, char *value, t_list *search_list); +static void is_plus(t_data *data, char **tmp, char *value, t_list *search_list); +static void is_equal(t_data *data, \ + char *key, char *value, t_list *search_list); + +void ft_update_env_export(t_data *data, char *key, char *value) +{ + int plus; + char *tmp; + t_list *search_list; + + plus = check_plus(key); + tmp = get_tmp_key(key, plus); + search_list = env_search(data, tmp, FALSE); + if (plus == FALSE) + { + is_not_plus(data, key, value, search_list); + free(tmp); + } + else + { + is_plus(data, &tmp, value, search_list); + free(key); + } +} + +static char *get_tmp_key(char *key, t_bool plus) +{ + int i; + char *tmp; + + tmp = ft_strdup(""); + if (plus == TRUE) + { + i = 0; + while (key[i] != '+') + i++; + tmp = ft_strncat(tmp, key, i); + } + else if (check_equal(key) == TRUE) + tmp = ft_strncat(tmp, key, ft_strlen(key) - 1); + else + tmp = ft_strncat(tmp, key, ft_strlen(key)); + return (tmp); +} + +static void is_not_plus(t_data *data, \ + char *key, char *value, t_list *search_list) +{ + if (check_equal(key) == FALSE) + { + if (search_list) + { + free(key); + free(value); + } + else + ft_add_env_front(data, key, value); + } + else + is_equal(data, key, value, search_list); +} + +static void is_plus(t_data *data, char **tmp, char *value, t_list *search_list) +{ + if (search_list) + { + if (check_equal(search_list->env) == TRUE) + search_list->env = \ + ft_strncat(search_list->env, value, ft_strlen(value)); + else + { + search_list->env = ft_strncat(search_list->env, "=", 1); + search_list->env = \ + ft_strncat(search_list->env, value, ft_strlen(value)); + } + free(value); + free(*tmp); + } + else + ft_add_env_front(data, *tmp, value); +} + +static void is_equal(t_data *data, \ + char *key, char *value, t_list *search_list) +{ + if (search_list) + { + free(search_list->env); + if (value) + { + search_list->env = ft_strncat(key, value, ft_strlen(value)); + free(value); + } + else + search_list->env = key; + } + else + ft_add_env_front(data, key, value); +} diff --git a/srcs/exec/sig.c b/srcs/exec/sig.c deleted file mode 100644 index 4981ae3..0000000 --- a/srcs/exec/sig.c +++ /dev/null @@ -1,55 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* sig.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: kichan +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2023/07/15 18:40:34 by kichlee #+# #+# */ -/* Updated: 2023/07/17 23:26:37 by kichan ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "../incs/minishell.h" - - -#include -#include - -// void set_terminal_print_off() { -// struct termios old_term, new_term; -// tcgetattr(fileno(stdin), &old_term); // 기존의 터미널 설정 가져오기 - -// new_term = old_term; -// new_term.c_lflag &= ~(ECHOCTL); // 시그널표식 출력이 true 라면 false로 변경 - -// tcsetattr(fileno(stdin), TCSANOW, &new_term); // 변경한 설정을 터미널에 적용 -// } - - -// void set_terminal_print_off(void) -// { -// struct termios term; // 터미널 설정이 담겨있는 termios 구조체 - -// tcgetattr(1, &term); // 현재 터미널의 설정을 term에 가져옴 -// term.c_lflag &= ~(ECHOCTL); // 시그널표식 출력이 true 라면 false로 변경 -// tcsetattr(1, 0, &term); // 변경한 term 설정을 현재 터미널에 적용 -// } - - -void handle_sigint(int sig) -{ - printf("\n"); - // rl_on_new_line(); - // rl_replace_line("", 0); - // rl_redisplay(); - (void) sig; -} - -void sig(char *command) -{ - signal(SIGINT, handle_sigint); - signal(SIGQUIT, SIG_IGN); - if(command) - free(command); -} \ No newline at end of file diff --git a/srcs/execute/child.c b/srcs/execute/child.c new file mode 100644 index 0000000..259936e --- /dev/null +++ b/srcs/execute/child.c @@ -0,0 +1,88 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* child.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: eunwolee +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/08/14 18:36:58 by eunwolee #+# #+# */ +/* Updated: 2023/08/17 16:40:49 by eunwolee ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../../incs/minishell.h" + +void do_cmd(t_data *data); +void exec_fork(t_data *data); +t_bool check_dir(char *command); +static t_bool check_relative_path(char *command); + +void do_cmd(t_data *data) +{ + int builtnum; + t_leaf *temp; + + temp = data->root->left_child->right_child; + if (data->info->pipe_num >= 300) + { + printf("%s\n", E_SYNTAX_PIPE); + exit(258); + } + if (temp != NULL) + builtnum = check_builtin_func(temp->token->str); + if (data->root->left_child->left_child != NULL) + check_redirect (data->root, data); + if (temp == NULL) + exit(0); + if (builtnum != 0) + { + exec_builtin(builtnum, data); + exit(0); + } + else + exec_fork(data); +} + +void exec_fork(t_data *data) +{ + t_pipe *base; + + base = data->pipe; + if (!data->root->left_child->right_child) + return ; + base->cmd_path = ft_join_cmd(data->root->left_child->right_child); + if (check_dir(base->cmd_path[0]) == TRUE) + { + error_print(base->cmd_path[0], 0, 2); + exit(126); + } + if (check_path(base->cmd_path[0]) == FALSE) + abs_path(data); + base->command = set_path(data); + if (!base->command) + { + if (check_relative_path(base->cmd_path[0]) == TRUE) + error_print(base->cmd_path[0], 0, 1); + else + error_print(base->cmd_path[0], 0, 0); + exit(127); + } + execve(base->command, base->cmd_path, data->env_array); +} + +t_bool check_dir(char *command) +{ + struct stat path_stat; + + if (check_relative_path(command) == TRUE) + if (stat(command, &path_stat) == 0 && S_ISDIR(path_stat.st_mode)) + return (TRUE); + return (FALSE); +} + +static t_bool check_relative_path(char *command) +{ + if (!ft_strncmp("./", command, 2) || !ft_strncmp("../", command, 3)) + return (TRUE); + return (FALSE); +} diff --git a/srcs/execute/execve.c b/srcs/execute/execve.c new file mode 100644 index 0000000..412aeb4 --- /dev/null +++ b/srcs/execute/execve.c @@ -0,0 +1,83 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* execve.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: eunwolee +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/08/14 18:31:21 by eunwolee #+# #+# */ +/* Updated: 2023/08/17 20:04:36 by eunwolee ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../../incs/minishell.h" + +void execute(t_data *data); +void execute_cmd(t_data *data, int flag); +static void execute_single_cmd(t_data *data, t_pipe *base, int i, int flag); + +void execute(t_data *data) +{ + count_pipe(data); + heredoc_flag(data->root, data); + data->info->heredoc_file = \ + (char **)ft_calloc(data->info->heredoc_flag + 1, sizeof(char *)); + if (!data->info->heredoc_file) + program_error_exit("bash"); + if (!data->info->pipe_num && !data->info->heredoc_flag) + if (check_builtin(data) == TRUE) + return ; + if (data->info->heredoc_flag) + { + if (fork_heredoc (data)) + return ; + } + execute_cmd(data, 0); +} + +void execute_cmd(t_data *data, int flag) +{ + int i; + t_pipe *base; + t_leaf *head; + + i = 0; + base = data->pipe; + head = data->root; + while (i < data->info->pipe_num + 1) + { + execute_single_cmd(data, base, i, flag); + i++; + } + data->root = head; + wait_child_processes(data); +} + +static void execute_single_cmd(t_data *data, t_pipe *base, int i, int flag) +{ + if (i < data->info->pipe_num) + if (pipe(base->com[i].fd) < 0) + error_back_readline(data, "bash", EPIPE, 1); + base->com[i].pid = fork(); + if (base->com[i].pid == -1) + { + if (flag) + program_error_exit("bash"); + else + error_back_readline(data, "bash", ENOMEM, 1); + } + if (base->com[i].pid == 0) + { + signal(SIGINT, child_handler); + signal(SIGQUIT, child_handler); + data->info->parent = 1; + if (data->info->pipe_num != 0) + if (link_pipe(i, base, data) > 0) + exit(1); + do_cmd(data); + } + else + data->root = data->root->right_child; + if (data->info->pipe_num) + close_pipe(i, base, data); +} diff --git a/srcs/execute/execve_utils.c b/srcs/execute/execve_utils.c new file mode 100644 index 0000000..e7ac03f --- /dev/null +++ b/srcs/execute/execve_utils.c @@ -0,0 +1,72 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* execve_utils.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: kichlee +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/08/14 18:39:07 by eunwolee #+# #+# */ +/* Updated: 2023/08/17 22:04:31 by kichlee ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../../incs/minishell.h" + +int check_builtin(t_data *data); +void recover_std(t_data *data); +void heredoc_flag(t_leaf *leaf, t_data *data); + +int check_builtin(t_data *data) +{ + int built; + t_leaf *temp; + + temp = data->root->left_child->right_child; + if (temp != NULL) + built = check_builtin_func(temp->token->str); + if (temp == NULL) + { + check_redirect(data->root, data); + recover_std(data); + return (TRUE); + } + if (built != 0) + { + if (!check_redirect(data->root, data)) + return (1); + g_error_code = exec_builtin(built, data); + recover_std(data); + return (TRUE); + } + return (FALSE); +} + +void recover_std(t_data *data) +{ + if (dup2(data->info->oristdin, STDIN_FILENO) == -1) + error_back_readline(data, "Bad file descriptor", EBADF, 1); + close(data->info->oristdin); + if (dup2(data->info->oristdout, STDOUT_FILENO) == -1) + error_back_readline(data, "Bad file descriptor", EBADF, 1); + close(data->info->oristdin); +} + +void heredoc_flag(t_leaf *leaf, t_data *data) +{ + if (!leaf) + return ; + if (leaf->token) + { + if (leaf->token->type == T_REDIRECT) + { + if (leaf->token->redirect_type == T_HEREDOC) + { + if (leaf->left_child == NULL) + return ; + data->info->heredoc_flag++; + } + } + } + heredoc_flag(leaf->left_child, data); + heredoc_flag(leaf->right_child, data); +} diff --git a/srcs/execute/file.c b/srcs/execute/file.c new file mode 100644 index 0000000..1362274 --- /dev/null +++ b/srcs/execute/file.c @@ -0,0 +1,42 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* file.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: kichlee +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/08/14 18:53:28 by eunwolee #+# #+# */ +/* Updated: 2023/08/17 22:04:04 by kichlee ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../../incs/minishell.h" + +int check_file(int fd, t_data *data); +void close_file(t_data *data); + +int check_file(int fd, t_data *data) +{ + char *str; + + str = data->root->left_child->left_child->left_child->token->str; + if (fd < 0) + { + close(fd); + g_error_code = 1; + error_print(str, 0, 1); + if (data->info->parent == 1) + exit(1); + return (0); + } + return (1); +} + +void close_file(t_data *data) +{ + int i; + + i = -1; + while (++i < data->info->index) + unlink(data->info->heredoc_file[i]); +} diff --git a/srcs/execute/parent.c b/srcs/execute/parent.c new file mode 100644 index 0000000..bf72e9d --- /dev/null +++ b/srcs/execute/parent.c @@ -0,0 +1,36 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* parent.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: eunwolee +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/08/14 18:37:35 by eunwolee #+# #+# */ +/* Updated: 2023/08/17 21:33:02 by eunwolee ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../../incs/minishell.h" + +void wait_child_processes(t_data *data) +{ + int i; + int status; + + i = 0; + signal (SIGINT, SIG_IGN); + while (i < data->info->pipe_num + 1) + { + if (wait(&status) \ + == data->pipe->com[data->info->pipe_num].pid) + g_error_code = WEXITSTATUS(status); + if (WIFSIGNALED(status) && !data->info->heredoc_flag) + g_error_code = 128 + WTERMSIG(status); + i++; + } + if (WTERMSIG (status) == 2) + ft_putendl_fd("", STDERR_FILENO); + else if (WTERMSIG (status) == 3) + ft_putendl_fd("Quit: 3", STDOUT_FILENO); + close_file(data); +} diff --git a/srcs/execute/path.c b/srcs/execute/path.c new file mode 100644 index 0000000..7affa79 --- /dev/null +++ b/srcs/execute/path.c @@ -0,0 +1,107 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* path.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: eunwolee +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/08/14 18:43:04 by eunwolee #+# #+# */ +/* Updated: 2023/08/17 16:41:54 by eunwolee ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../../incs/minishell.h" + +char *set_path(t_data *data); +void abs_path(t_data *data); +int check_path(char *str); +char *search_path(t_pipe *base); +static char **get_path_envp(char **env); + +char *set_path(t_data *data) +{ + char *tmp; + t_pipe *base; + + base = data->pipe; + if (!base->cmd_path) + exit(1); + if (check_path(base->cmd_path[0]) == TRUE) + { + tmp = ft_strdup(base->cmd_path[0]); + if (access(tmp, X_OK) == 0) + return (tmp); + free(tmp); + return (NULL); + } + return (search_path(base)); +} + +void abs_path(t_data *data) +{ + int i; + char *temp; + + i = 0; + data->pipe->cmd_abs = get_path_envp(data->env_array); + if (!data->pipe->cmd_abs || !data->pipe->cmd_abs[1]) + return ; + while (data->pipe->cmd_abs[i]) + { + temp = data->pipe->cmd_abs[i]; + data->pipe->cmd_abs[i] = ft_strjoin(temp, "/"); + free(temp); + i++; + } +} + +int check_path(char *str) +{ + if (!ft_strncmp("./", str, 2) || \ + !ft_strncmp("../", str, 3) || \ + !ft_strncmp("/", str, 1)) + return (1); + return (0); +} + +char *search_path(t_pipe *base) +{ + char *tmp; + int k; + + k = 0; + if (!base->cmd_abs) + { + error_print(base->cmd_path[0], 0, 1); + exit (127); + } + while (base->cmd_abs[k]) + { + tmp = ft_strjoin(base->cmd_abs[k], base->cmd_path[0]); + if (access(tmp, X_OK) == 0) + return (tmp); + free(tmp); + k++; + } + return (NULL); +} + +static char **get_path_envp(char **env) +{ + char *path; + int i; + + i = 0; + if (*env == NULL) + return (NULL); + while (env[i]) + { + if (ft_strncmp("PATH=", env[i], 5) == 0) + { + path = env[i]; + return (ft_split(path, ':')); + } + i++; + } + return (NULL); +} diff --git a/srcs/execute/pipe.c b/srcs/execute/pipe.c new file mode 100644 index 0000000..9a9b9d9 --- /dev/null +++ b/srcs/execute/pipe.c @@ -0,0 +1,73 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* pipe.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: eunwolee +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/08/14 18:38:38 by eunwolee #+# #+# */ +/* Updated: 2023/08/17 12:03:24 by eunwolee ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../../incs/minishell.h" + +int link_pipe(int i, t_pipe *base, t_data *data); +void close_pipe(int i, t_pipe *base, t_data *data); +void count_pipe(t_data *data); + +int link_pipe(int i, t_pipe *base, t_data *data) +{ + if (i == data->info->pipe_num) + { + if (dup2(base->com[i - 1].fd[0], STDIN_FILENO) == -1 \ + || close(base->com[i - 1].fd[0]) == -1) + return (1); + } + else if (i == 0) + { + if (close(base->com[i].fd[0]) == -1 \ + || dup2(base->com[i].fd[1], STDOUT_FILENO) == -1 \ + || close(base->com[i].fd[1]) == -1) + return (1); + } + else + { + if (close(base->com[i].fd[0]) == -1 \ + || dup2(base->com[i - 1].fd[0], STDIN_FILENO) == -1 \ + || dup2(base->com[i].fd[1], STDOUT_FILENO) == -1) + return (1); + } + return (0); +} + +void close_pipe(int i, t_pipe *base, t_data *data) +{ + if (i == data->info->pipe_num) + close(base->com[i - 1].fd[0]); + else if (i == 0) + close(base->com[i].fd[1]); + else + { + close(base->com[i - 1].fd[0]); + close(base->com[i].fd[1]); + } +} + +void count_pipe(t_data *data) +{ + t_leaf *temp; + + temp = data->root; + while (temp) + { + data->info->pipe_num++; + temp = temp->right_child; + } + if (data->info->pipe_num != 0) + data->info->pipe_num--; + data->pipe->com = \ + (t_pid *)ft_calloc(data->info->pipe_num + 1, sizeof(t_pid)); + if (!data->pipe->com) + program_error_exit("bash"); +} diff --git a/srcs/init/init.c b/srcs/init/init.c index 06a0839..35fc6c6 100644 --- a/srcs/init/init.c +++ b/srcs/init/init.c @@ -6,16 +6,17 @@ /* By: eunwolee +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/06/29 11:06:52 by eunwolee #+# #+# */ -/* Updated: 2023/07/21 08:50:37 by eunwolee ### ########.fr */ +/* Updated: 2023/08/17 13:30:40 by eunwolee ### ########.fr */ /* */ /* ************************************************************************** */ -#include "../incs/minishell.h" +#include "../../incs/minishell.h" void init(t_data **data, char **envp); void env_init(t_data *data, char **envp); +void pipe_init(t_pipe **pipe); +void info_init(t_info **info); -//필요하신 초기화 내용 여기 넣어주시면 됩니당 void init(t_data **data, char **envp) { *data = (t_data *)ft_calloc(1, sizeof(t_data)); @@ -33,11 +34,26 @@ void env_init(t_data *data, char **envp) while (envp[++i]) { new = ft_lstnew(); - if (!new) - program_error_exit("bash"); new->env = ft_strdup(envp[i]); + new->equal_flag = 0; if (!new->env) program_error_exit("bash"); ft_lstadd_back(&data->envs, new); } } + +void pipe_init(t_pipe **pipe) +{ + *pipe = (t_pipe *)ft_calloc(1, sizeof(t_pipe)); + if (!*pipe) + program_error_exit("bash"); +} + +void info_init(t_info **info) +{ + *info = (t_info *)ft_calloc(1, sizeof(t_info)); + if (!*info) + program_error_exit("bash"); + (*info)->oristdin = dup(STDIN_FILENO); + (*info)->oristdout = dup(STDOUT_FILENO); +} diff --git a/srcs/input/get_input.c b/srcs/input/get_input.c new file mode 100644 index 0000000..55d6dce --- /dev/null +++ b/srcs/input/get_input.c @@ -0,0 +1,56 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* get_input.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: kichlee +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/08/14 18:27:16 by eunwolee #+# #+# */ +/* Updated: 2023/08/17 21:39:51 by kichlee ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../../incs/minishell.h" + +t_bool get_input(t_data *data); +static t_bool check_blank_input(char *str); + +t_bool get_input(t_data *data) +{ + data->input = readline("minishell$ "); + if (!data->input) + { + printf("exit\n"); + g_error_code = 0; + exit(0); + } + add_history(data->input); + if (check_blank_input(data->input) == TRUE || lexer(data) == FALSE) + { + free(data->input); + return (FALSE); + } + if (syntax(data) == FALSE) + { + tree_clear(data->root); + ft_lstclear(&data->tokens); + free(data->input); + return (FALSE); + } + parser(data); + pipe_init(&data->pipe); + info_init(&data->info); + return (TRUE); +} + +static t_bool check_blank_input(char *str) +{ + int i; + + i = 0; + while (str[i] == ' ' || str[i] == '\t') + i++; + if (str[i] == '\0') + return (TRUE); + return (FALSE); +} diff --git a/srcs/lexer/.DS_Store b/srcs/lexer/.DS_Store new file mode 100644 index 0000000..4959638 Binary files /dev/null and b/srcs/lexer/.DS_Store differ diff --git a/srcs/lexer/expand.c b/srcs/lexer/expand.c index 7c7c81c..999b948 100644 --- a/srcs/lexer/expand.c +++ b/srcs/lexer/expand.c @@ -3,123 +3,52 @@ /* ::: :::::::: */ /* expand.c :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: kichlee +#+ +:+ +#+ */ +/* By: eunwolee +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/07/11 12:20:49 by eunwolee #+# #+# */ -<<<<<<< HEAD -/* Updated: 2023/07/21 15:56:43 by eunwolee ### ########.fr */ -======= -/* Updated: 2023/07/21 17:31:43 by kichlee ### ########.fr */ ->>>>>>> 78a3320df2eb8d80f749bde9f55419632351d2e3 +/* Updated: 2023/08/17 20:30:21 by eunwolee ### ########.fr */ /* */ /* ************************************************************************** */ #include "../../incs/minishell.h" -t_bool expand(t_data *data, t_token *token, int *i, t_bool quote); -static t_bool check_heredoc(t_data *data, t_token *token, int *i); -static t_bool check_blank(t_data *data, t_token *token, int *i, t_bool quote); -static t_bool check_other(t_data *data, t_token *token, int *i, t_bool quote); +t_bool expand(t_data *data, t_token **token, int *i, t_bool quote); static void replace(t_data *data, t_token *token, char *name); +static char *get_name(t_data *data, int *i); -//환경변수 뒤에 숫자 알파벳 외에는 환경변수 치환해야함 -t_bool expand(t_data *data, t_token *token, int *i, t_bool quote) +t_bool expand(t_data *data, t_token **token, int *i, t_bool quote) { char *name; *i += 1; - name = NULL; - if (check_heredoc(data, token, i) == TRUE) - return (TRUE); - if (check_blank(data, token, i, quote) == TRUE) - return (TRUE); - if (check_other(data, token, i, quote) == TRUE) - return (TRUE); - while (data->input[*i] != '\'' && data->input[*i] != '\"' \ - && data->input[*i] != ' ' && data->input[*i] != '\t' \ - && data->input[*i] != '\0' && ft_isalnum(data->input[*i])) + if (check_heredoc(data, *token, i) == FALSE \ + && check_question(data, *token, i) == FALSE \ + && check_d_quote(data, *token, i, quote) == FALSE \ + && check_other(data, *token, i, quote) == FALSE \ + && check_special(data, *token, i) == FALSE) { - name = ft_strncat(name, &data->input[*i], 1); - if (!name) - program_error_exit("bash"); - *i += 1; + name = get_name(data, i); + replace(data, *token, name); } - replace(data, token, name); if (quote == FALSE) - *i -= 1; - else if (quote == TRUE && data->input[*i] == '\"') - return (TRUE); - return (FALSE); -} - -static t_bool check_heredoc(t_data *data, t_token *token, int *i) -{ - t_list *tmp; - - tmp = ft_lstlast(data->tokens); - if (tmp && tmp->token->redirect_type == T_HEREDOC) { - token->str = ft_strncat(token->str, "$", 1); - if (!token->str) - program_error_exit("bash"); + (*token)->blank = check_end(data->input[*i]); *i -= 1; - return (TRUE); } return (FALSE); } -static t_bool check_blank(t_data *data, t_token *token, int *i, t_bool quote) +static char *get_name(t_data *data, int *i) { - if (quote == FALSE && (data->input[*i] == ' ' || data->input[*i] == '\t')) - { - token->str = ft_strncat(token->str, "$", 1); - if (!token->str) - program_error_exit("bash"); - if (quote == FALSE) - { - *i -= 1; - return (TRUE); - } - token->str = ft_strncat(token->str, &data->input[*i], 1); - if (!token->str) - program_error_exit("bash"); - if (quote == TRUE) - return (TRUE); - } - return (FALSE); -} + char *name; -static t_bool check_other(t_data *data, t_token *token, int *i, t_bool quote) -{ - if (data->input[*i] == '\"') - { - if (quote == TRUE) - { - token->str = ft_strncat(token->str, "$", 1); - if (!token->str) - program_error_exit("bash"); - } - else - { - if (data->input[*i + 1] == '\0') - return (FALSE); - *i -= 1; - } - return (TRUE); - } - else if (data->input[*i] == '\'') - { - *i -= 1 ; - return (TRUE); - } - else if (data->input[*i] == '\0') + name = ft_strdup(""); + while (ft_isalnum(data->input[*i]) || data->input[*i] == '_') { - token->str = ft_strncat(token->str, "$", 1); - if (!token->str) - program_error_exit("bash"); - return (TRUE); + name = ft_strncat(name, &data->input[*i], 1); + *i += 1; } - return (FALSE); + return (name); } static void replace(t_data *data, t_token *token, char *name) @@ -127,25 +56,14 @@ static void replace(t_data *data, t_token *token, char *name) int j; t_list *tmp; - tmp = env_search(data, name); - if (!tmp) - { - token->str = ft_strdup("$"); - if (!token->str) - program_error_exit("bash"); - token->str = ft_strncat(token->str, name, ft_strlen(name)); - if (!token->str) - program_error_exit("bash"); - } - else + tmp = env_search(data, name, TRUE); + if (tmp) { j = 0; while (tmp->env[j] != '=') j++; token->str = ft_strncat(token->str, \ &tmp->env[j + 1], ft_strlen(&tmp->env[j + 1])); - if (!token->str) - program_error_exit("bash"); } - free(name); // test. + free(name); } diff --git a/srcs/lexer/expand_check.c b/srcs/lexer/expand_check.c new file mode 100644 index 0000000..641f474 --- /dev/null +++ b/srcs/lexer/expand_check.c @@ -0,0 +1,100 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* expand_check.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: eunwolee +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/08/13 16:23:58 by eunwolee #+# #+# */ +/* Updated: 2023/08/17 21:29:36 by eunwolee ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../../incs/minishell.h" + +t_bool check_heredoc(t_data *data, t_token *token, int *i); +t_bool check_question(t_data *data, t_token *token, int *i); +t_bool check_d_quote(t_data *data, t_token *token, int *i, t_bool quote); +t_bool check_other(t_data *data, t_token *token, int *i, t_bool quote); +t_bool check_special(t_data *data, t_token *token, int *i); + +t_bool check_heredoc(t_data *data, t_token *token, int *i) +{ + t_list *tmp; + + tmp = ft_lstlast(data->tokens); + if (tmp && tmp->token->redirect_type == T_HEREDOC) + { + token->str = ft_strncat(token->str, "$", 1); + *i -= 1; + return (TRUE); + } + return (FALSE); +} + +t_bool check_question(t_data *data, t_token *token, int *i) +{ + char *tmp; + + if (data->input[*i] == '?') + { + tmp = ft_itoa(g_error_code); + token->str = ft_strncat(token->str, tmp, ft_strlen(tmp)); + token->blank = check_end(data->input[*i + 1]); + *i += 1; + free(tmp); + return (TRUE); + } + return (FALSE); +} + +t_bool check_d_quote(t_data *data, t_token *token, int *i, t_bool quote) +{ + int idx; + + if (data->input[*i] == '\"') + { + idx = *i; + if (quote == FALSE) + while (data->input[idx + 1] != '\"' && data->input[idx + 1] != '\0') + idx++; + if (quote == TRUE || check_end(data->input[idx + 1]) == TRUE) + token->str = ft_strncat(token->str, "$", 1); + return (TRUE); + } + return (FALSE); +} + +t_bool check_other(t_data *data, t_token *token, int *i, t_bool quote) +{ + if (quote == FALSE && (data->input[*i] == ' ' || data->input[*i] == '\t')) + { + token->str = ft_strncat(token->str, "$", 1); + return (TRUE); + } + else if (data->input[*i] == '\'') + return (TRUE); + else if (data->input[*i] == '\0') + { + token->str = ft_strncat(token->str, "$", 1); + return (TRUE); + } + return (FALSE); +} + +t_bool check_special(t_data *data, t_token *token, int *i) +{ + if (!ft_isalpha(data->input[*i]) && data->input[*i] != '_') + { + token->str = ft_strncat(token->str, "$", 1); + while (!ft_isalpha(data->input[*i]) \ + && data->input[*i] != '$' \ + && check_end(data->input[*i]) == FALSE) + { + token->str = ft_strncat(token->str, &data->input[*i], 1); + *i += 1; + } + return (TRUE); + } + return (FALSE); +} diff --git a/srcs/lexer/lexer.c b/srcs/lexer/lexer.c index a71ca98..32e4144 100644 --- a/srcs/lexer/lexer.c +++ b/srcs/lexer/lexer.c @@ -3,57 +3,86 @@ /* ::: :::::::: */ /* lexer.c :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: eunwolee +#+ +:+ +#+ */ +/* By: kichlee +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/06/29 16:24:37 by eunwolee #+# #+# */ -/* Updated: 2023/07/21 15:56:51 by eunwolee ### ########.fr */ +/* Updated: 2023/08/19 17:01:28 by kichlee ### ########.fr */ /* */ /* ************************************************************************** */ #include "../../incs/minishell.h" -void lexer(t_data *data); -static void check_char(t_data *data, t_token **token, int *i); +t_bool lexer(t_data *data); +static void check_char(t_data *data, t_token **token, int *i, t_bool *pre_pipe); +static void blank_char(t_data *data, t_token **token, int *i, t_bool *pre_pipe); +static void normal_char(t_data *data, t_token **token, int *i); -void lexer(t_data *data) +t_bool lexer(t_data *data) { int i; t_token *token; + t_bool pre_pipe; + t_list *last_token; + pre_pipe = FALSE; token = token_create(); - if (!token) - program_error_exit("bash"); i = -1; while (data->input[++i]) - check_char(data, &token, &i); - if (token->str && *(token->str)) - token_add_list(&data->tokens, &token, FALSE); + check_char(data, &token, &i, &pre_pipe); + free(token->str); + free(token); + if (!data->tokens) + return (FALSE); + last_token = ft_lstlast(data->tokens); + last_token->token->blank = FALSE; + return (TRUE); } -static void check_char(t_data *data, t_token **token, int *i) +static void check_char(t_data *data, t_token **token, int *i, t_bool *pre_pipe) { if (data->input[*i] == '|' \ - || data->input[*i] == '<' || data->input[*i] == '>') - { - if (*(*token)->str) - token_add_list(&data->tokens, token, TRUE); + || data->input[*i] == '<' \ + || data->input[*i] == '>' \ + || data->input[*i] == '\'' \ + || data->input[*i] == '\"') tokenizer(data, token, i); - } - else if (data->input[*i] == '\'' || data->input[*i] == '\"') + else if (data->input[*i] == '$') { - tokenizer(data, token, i); + expand(data, token, i, FALSE); + token_add_list(&data->tokens, token); } else if (data->input[*i] == ' ' || data->input[*i] == '\t') - { - if (*(*token)->str) - token_add_list(&data->tokens, token, TRUE); - } - else if (data->input[*i] == '$') - expand(data, *token, i, FALSE); + blank_char(data, token, i, pre_pipe); else + normal_char(data, token, i); +} + +static void blank_char(t_data *data, t_token **token, int *i, t_bool *pre_pipe) +{ + if (*pre_pipe == TRUE) { - (*token)->str = ft_strncat((*token)->str, &data->input[*i], 1); - if (!(*token)->str) - program_error_exit("bash"); + *pre_pipe = FALSE; + return ; } + while (data->input[*i] == ' ' || data->input[*i] == '\t') + *i += 1; + if (data->input[*i] == '|') + *pre_pipe = TRUE; + token_add_list(&data->tokens, token); + *i -= 1; +} + +static void normal_char(t_data *data, t_token **token, int *i) +{ + (*token)->blank = FALSE; + (*token)->str = ft_strncat((*token)->str, &data->input[*i], 1); + (*token)->blank = check_last_blank(data->input, *i + 1); + if (data->input[*i + 1] == '|' \ + || data->input[*i + 1] == '<' \ + || data->input[*i + 1] == '>' \ + || data->input[*i + 1] == '\'' \ + || data->input[*i + 1] == '\"' \ + || data->input[*i + 1] == '$' \ + || data->input[*i + 1] == '\0') + token_add_list(&data->tokens, token); } diff --git a/srcs/lexer/lexer_utils.c b/srcs/lexer/lexer_utils.c new file mode 100644 index 0000000..391f1f8 --- /dev/null +++ b/srcs/lexer/lexer_utils.c @@ -0,0 +1,48 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* lexer_utils.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: kichlee +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/08/12 15:15:15 by eunwolee #+# #+# */ +/* Updated: 2023/08/19 17:01:32 by kichlee ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../../incs/minishell.h" + +t_bool check_end(char c); +t_bool check_last_blank(char *str, int i); +void quote_utils(char *input, t_token **token, int *i); + +t_bool check_end(char c) +{ + if (c == ' ' || c == '\t' || c == '\0') + return (TRUE); + return (FALSE); +} + +t_bool check_last_blank(char *str, int i) +{ + char c; + + c = str[i]; + while (c == '\'' || c == '\"') + { + c = str[i]; + if (str[i + 1] == c) + i += 2; + else + break ; + } + return (check_end(str[i])); +} + +void quote_utils(char *input, t_token **token, int *i) +{ + if (check_end(input[*i + 1]) == FALSE) + (*token)->blank = FALSE; + if (input[*i] == '\0') + *i -= 1; +} diff --git a/srcs/lexer/quote.c b/srcs/lexer/quote.c index cce7479..9ff5f09 100644 --- a/srcs/lexer/quote.c +++ b/srcs/lexer/quote.c @@ -6,79 +6,82 @@ /* By: eunwolee +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/07/03 07:46:30 by eunwolee #+# #+# */ -/* Updated: 2023/07/16 20:16:29 by eunwolee ### ########.fr */ +/* Updated: 2023/08/17 13:29:07 by eunwolee ### ########.fr */ /* */ /* ************************************************************************** */ #include "../../incs/minishell.h" -void single_quote(char *input, t_token *token, int *i); -void double_quote(char *input, t_token *token, int *i, t_data *data); +void single_quote(char *input, t_token **token, int *i); +void double_quote(t_data *data, \ + char *input, t_token **token, int *i); static t_bool find_next_quote(char *input, t_token *token, int i, char quote); -static t_bool s_check_char(char *input, t_token *token, int *i, t_bool next_quote); -static t_bool d_check_char(char *input, t_token *token, int *i, t_bool next_quote); +static t_bool s_check_char(char *input, \ + t_token *token, int *i, t_bool next_quote); +static t_bool d_check_char(char *input, \ + t_token *token, int *i, t_bool next_quote); -void single_quote(char *input, t_token *token, int *i) +void single_quote(char *input, t_token **token, int *i) { t_bool next_quote; *i += 1; - next_quote = find_next_quote(input, token, *i, '\''); + if (input[*i] == '\'') + (*token)->blank = FALSE; + next_quote = find_next_quote(input, (*token), *i, '\''); + if (next_quote == TRUE) + (*token)->quote = T_SINGLE; while (input[*i] != '\'' && input[*i] != '\0') { - if (s_check_char(input, token, i, next_quote) == TRUE) + if (s_check_char(input, *token, i, next_quote) == TRUE) return ; *i += 1; } - if (input[*i] == '\0') - *i -= 1; + quote_utils(input, token, i); } -void double_quote(char *input, t_token *token, int *i, t_data *data) +void double_quote(t_data *data, char *input, t_token **token, int *i) { t_bool next_quote; *i += 1; - next_quote = find_next_quote(input, token, *i, '\"'); + if (input[*i] == '\"') + (*token)->blank = FALSE; + next_quote = find_next_quote(input, *token, *i, '\"'); + if (next_quote == TRUE) + (*token)->quote = T_DOUBLE; while (input[*i] != '\"' && input[*i] != '\0') { - if (input[*i] == '$') + if (input[*i] == '$' && input[*i + 1] == '\"') { - if (input[*i + 1] != '\'' && next_quote == TRUE) - if (expand(data, token, i, TRUE) == TRUE) - return ; + (*token)->str = ft_strncat((*token)->str, &input[*i], 1); + *i += 1; + continue ; } - if (d_check_char(input, token, i, next_quote) == TRUE) - return ; + while (input[*i] == '$' && input[*i + 1] != '\'') + if (expand(data, token, i, TRUE) == TRUE) + break ; + if (d_check_char(input, *token, i, next_quote) == TRUE) + break ; *i += 1; } - if (input[*i] == '\0') - *i -= 1; + quote_utils(input, token, i); } static t_bool find_next_quote(char *input, t_token *token, int i, char quote) { - if (quote == '\"') - while (input[i] != quote && input[i] != '\0') - { - if (input[i] == '\\' && input[i + 1] == quote) - i++; - i++; - } - else - while (input[i] != quote && input[i] != '\0') - i++; + while (input[i] != quote && input[i] != '\0') + i++; if (input[i] == '\0') { token->str = ft_strncat(token->str, "e, 1); - if (!token->str) - program_error_exit("bash"); return (FALSE); } return (TRUE); } -static t_bool s_check_char(char *input, t_token *token, int *i, t_bool next_quote) +static t_bool s_check_char(char *input, \ + t_token *token, int *i, t_bool next_quote) { if (next_quote == FALSE \ && (input[*i] != ' ' || input[*i] != '\t')) @@ -88,27 +91,21 @@ static t_bool s_check_char(char *input, t_token *token, int *i, t_bool next_quot } else token->str = ft_strncat(token->str, &input[*i], 1); - if (!token->str) - program_error_exit("bash"); return (FALSE); } -static t_bool d_check_char(char *input, t_token *token, int *i, t_bool next_quote) +static t_bool d_check_char(char *input, \ + t_token *token, int *i, t_bool next_quote) { + if (next_quote == TRUE && input[*i] == '\"') + return (TRUE); if (next_quote == FALSE \ && (input[*i] != ' ' || input[*i] != '\t')) { *i -= 1; return (TRUE); } - if (input[*i] == '\\' && input[*i + 1] == '\"') - { - token->str = ft_strncat(token->str, "\\\"", 2); - *i += 1; - } else token->str = ft_strncat(token->str, &input[*i], 1); - if (!token->str) - program_error_exit("bash"); return (FALSE); -} \ No newline at end of file +} diff --git a/srcs/lexer/tokenizer.c b/srcs/lexer/tokenizer.c index 5433ee4..88ee189 100644 --- a/srcs/lexer/tokenizer.c +++ b/srcs/lexer/tokenizer.c @@ -6,7 +6,7 @@ /* By: eunwolee +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/07/11 12:26:13 by eunwolee #+# #+# */ -/* Updated: 2023/07/21 09:06:12 by eunwolee ### ########.fr */ +/* Updated: 2023/08/17 20:28:42 by eunwolee ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,23 +15,19 @@ void tokenizer(t_data *data, t_token **token, int *i); t_token *token_create(void); void token_redirect(t_data *data, t_token *token, int *i); -void token_add_list(t_list **head, t_token **token, t_bool token_flag); +void token_add_list(t_list **head, t_token **token); void tokenizer(t_data *data, t_token **token, int *i) { if (data->input[*i] == '|') (*token)->type = T_PIPE; else if (data->input[*i] == '\"') - double_quote(data->input, *token, i, data); + double_quote(data, data->input, token, i); else if (data->input[*i] == '\'') - single_quote(data->input, *token, i); + single_quote(data->input, token, i); else if (data->input[*i] == '<' || data->input[*i] == '>') token_redirect(data, *token, i); - if ((data->input[*i] == '\'' || data->input[*i] == '\"') \ - && (data->input[*i + 1] != ' ' && data->input[*i + 1] != '\t') \ - && (data->input[*i + 1] != '\0')) - return ; - token_add_list(&data->tokens, token, TRUE); + token_add_list(&data->tokens, token); } t_token *token_create(void) @@ -41,10 +37,9 @@ t_token *token_create(void) token = (t_token *)ft_calloc(1, sizeof(t_token)); if (!token) program_error_exit("bash"); + token->blank = TRUE; token->type = T_WORD; token->str = ft_strdup(""); - if (!token->str) - program_error_exit("bash"); return (token); } @@ -73,19 +68,14 @@ void token_redirect(t_data *data, t_token *token, int *i) } } -void token_add_list(t_list **head, t_token **token, t_bool token_flag) +void token_add_list(t_list **head, t_token **token) { t_list *new; + if ((*token)->type == T_WORD && !(*token)->str[0]) + return ; new = ft_lstnew(); - if (!new) - program_error_exit("bash"); new->token = *token; ft_lstadd_back(head, new); - if (token_flag == TRUE) - { - *token = token_create(); - if (!*token) - program_error_exit("bash"); - } + *token = token_create(); } diff --git a/srcs/minishell.c b/srcs/minishell.c index 248f476..869ee63 100644 --- a/srcs/minishell.c +++ b/srcs/minishell.c @@ -3,75 +3,31 @@ /* ::: :::::::: */ /* minishell.c :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: eunwolee +#+ +:+ +#+ */ +/* By: kichlee +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/06/29 11:06:49 by eunwolee #+# #+# */ -/* Updated: 2023/07/21 15:58:00 by eunwolee ### ########.fr */ +/* Updated: 2023/08/17 21:52:03 by kichlee ### ########.fr */ /* */ /* ************************************************************************** */ #include "../incs/minishell.h" -int main(int argc, char **argv, char **envp) +int main(int argc, char **argv, char **envp) { - t_data *data; - char *command = NULL; - (void)argc; + t_data *data; + (void)argv; init(&data, envp); - - while (1) + init_base(argc); + data->env_array = env_to_array(data); + while (TRUE) { - sig(command); - command = readline("minishell$ "); - if (!command) - { - printf("exit\n"); - return (0); - } - data->input = ft_substr(command, 0, ft_strlen(command)); - lexer(data); - syntax(data); - parser(data); - - if (ft_strncmp(data->root->left_child->right_child->token->str, "cd", 2) == 0) - { - // printf("cd check!"); - ft_cd(data); - printf("data name : %s\n", data->root->left_child->right_child->right_child->token->str); - // printf("%s", env_search(data, "HOME")->env); + sig(); + if (get_input(data) == FALSE) + continue ; + execute(data); + input_free(data); } - if (ft_strncmp(data->root->left_child->right_child->token->str, "echo", 4) == 0) - { - // printf("echo check!"); - ft_echo(data); - } - if (ft_strncmp(data->root->left_child->right_child->token->str, "exit", 4) == 0) - { - // printf("exit check!"); - ft_exit(data); - } - if (ft_strncmp(data->root->left_child->right_child->token->str, "pwd", 3) == 0) - { - // printf("pwd check!"); - ft_pwd(); - } - if (ft_strncmp(data->root->left_child->right_child->token->str, "unset", 5) == 0) - { - // printf("unset check!"); - ft_unset(data); - } - if (ft_strncmp(data->root->left_child->right_child->token->str, "export", 5) == 0) - { - // printf("export check!"); - ft_export(data); - } - - // print_token(data); - // printf("\n\n"); - // tree_print(data->root); - // builtin_cd(data, &command); - } - + data_free(data); return (0); } diff --git a/srcs/parser/syntax.c b/srcs/parser/syntax.c index 8e58659..5e9b56c 100644 --- a/srcs/parser/syntax.c +++ b/srcs/parser/syntax.c @@ -6,7 +6,7 @@ /* By: eunwolee +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/07/07 22:24:38 by eunwolee #+# #+# */ -/* Updated: 2023/07/17 06:40:42 by eunwolee ### ########.fr */ +/* Updated: 2023/08/17 21:20:49 by eunwolee ### ########.fr */ /* */ /* ************************************************************************** */ @@ -49,8 +49,10 @@ static t_bool syntax_none(t_data *data, t_list *cur) { if (cur->token->type == T_WORD) cur->token->type = T_CMD; + if (cur->token->type == T_REDIRECT && !cur->next) + return (error_back_readline(data, E_SYNTAX_NEWLINE, 258, 0)); else if (cur->token->type == T_PIPE) - return (error_back_readline(data, E_SYNTAX_PIPE, 258)); + return (error_back_readline(data, E_SYNTAX_PIPE, 258, 0)); return (TRUE); } @@ -72,26 +74,26 @@ static t_bool syntax_redirect(t_data *data, t_list *cur) if (cur->pre->token->type == T_REDIRECT) { if (cur->token->redirect_type == T_INPUT) - return (error_back_readline(data, E_SYNTAX_INPUT, 258)); + return (error_back_readline(data, E_SYNTAX_INPUT, 258, 0)); if (cur->token->redirect_type == T_OUTPUT) - return (error_back_readline(data, E_SYNTAX_OUTPUT, 258)); + return (error_back_readline(data, E_SYNTAX_OUTPUT, 258, 0)); if (cur->token->redirect_type == T_HEREDOC) - return (error_back_readline(data, E_SYNTAX_HEREDOC, 258)); + return (error_back_readline(data, E_SYNTAX_HEREDOC, 258, 0)); if (cur->token->redirect_type == T_APPEND) - return (error_back_readline(data, E_SYNTAX_APPEND, 258)); + return (error_back_readline(data, E_SYNTAX_APPEND, 258, 0)); } if (!cur->next) - return (error_back_readline(data, E_SYNTAX_NEWLINE, 258)); + return (error_back_readline(data, E_SYNTAX_NEWLINE, 258, 0)); return (TRUE); } static t_bool syntax_pipe(t_data *data, t_list *cur) { if (cur->pre->token->type == T_PIPE) - return (error_back_readline(data, E_SYNTAX_PIPE, 258)); + return (error_back_readline(data, E_SYNTAX_PIPE, 258, 0)); if (cur->pre->token->type == T_REDIRECT) - return (error_back_readline(data, E_SYNTAX_PIPE, 258)); + return (error_back_readline(data, E_SYNTAX_PIPE, 258, 0)); if (!cur->next) - return (error_back_readline(data, E_SYNTAX_NEWLINE, 258)); + return (error_back_readline(data, E_SYNTAX_NEWLINE, 258, 0)); return (TRUE); } diff --git a/srcs/redirect/heredoc.c b/srcs/redirect/heredoc.c new file mode 100644 index 0000000..ae3d2e8 --- /dev/null +++ b/srcs/redirect/heredoc.c @@ -0,0 +1,122 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* heredoc.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: eunwolee +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/08/13 16:21:48 by eunwolee #+# #+# */ +/* Updated: 2023/08/17 21:31:47 by eunwolee ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../../incs/minishell.h" + +int fork_heredoc(t_data *data); +static void mk_heredoc_pipe(t_data *data); +static char *mk_filename(void); +static void mk_num(char *str, int num); +static void do_heredoc(t_leaf *leaf, t_data *data); + +int fork_heredoc(t_data *data) +{ + int status; + pid_t pid; + + pid = fork(); + if (pid == 0) + { + signal (SIGINT, child_handler); + mk_heredoc_pipe(data); + execute_cmd(data, 1); + exit(g_error_code); + } + else + { + signal (SIGINT, SIG_IGN); + waitpid(-1, &status, 0); + g_error_code = WEXITSTATUS(status); + if (WIFSIGNALED(status)) + { + g_error_code = WTERMSIG (status); + ft_putendl_fd("", STDERR_FILENO); + return (1); + } + } + return (1); +} + +static void mk_heredoc_pipe(t_data *data) +{ + t_leaf *pipe; + + pipe = data->root; + while (pipe) + { + data->info->heredoc_file[data->info->index] = mk_filename(); + if (pipe->left_child->left_child \ + && pipe->left_child->left_child->token->redirect_type == T_HEREDOC) + { + do_heredoc(pipe->left_child->left_child, data); + data->info->index++; + } + pipe = pipe->right_child; + } +} + +static char *mk_filename(void) +{ + char *str; + int exist; + int i; + + str = ft_strdup("/tmp/here_doc000"); + i = 0; + exist = 0; + while (exist == 0) + { + mk_num(str, i++); + exist = access(str, F_OK); + if (exist != 0) + unlink(str); + } + return (str); +} + +static void mk_num(char *str, int num) +{ + int i; + int j; + + i = 0; + j = 1; + while (i < 3) + { + if (i == 0) + { + str[13 + i++] = num / 100 + '0'; + num %= 100; + } + str[13 + i++] = num / (100 / (j * 10)) + '0'; + num %= (100 / (j * 10)); + j *= 10; + } +} + +static void do_heredoc(t_leaf *leaf, t_data *data) +{ + int fd; + t_leaf *temp; + + temp = leaf; + while (temp) + { + if (temp->token->redirect_type == T_HEREDOC) + { + fd = open(data->info->heredoc_file[data->info->index], \ + O_WRONLY | O_CREAT | O_TRUNC, 0644); + write_str(data, temp->left_child->token->str, fd); + } + temp = temp ->left_child; + } +} diff --git a/srcs/redirect/heredoc_parser.c b/srcs/redirect/heredoc_parser.c new file mode 100644 index 0000000..c93d7df --- /dev/null +++ b/srcs/redirect/heredoc_parser.c @@ -0,0 +1,111 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* heredoc_parser.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: eunwolee +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/08/13 16:16:20 by eunwolee #+# #+# */ +/* Updated: 2023/08/17 21:32:54 by eunwolee ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../../incs/minishell.h" + +void write_str(t_data *data, char *content, int fd); +static void heredoc_parser(t_data *data, int fd, char *str); +static char *heredoc_question(t_data *data, char *tmp, int *i); +static char *heredoc_expand(t_data *data, char *str, char *tmp, int *i); +static void heredoc_replace(t_data *data, char **tmp, char *name); + +void write_str(t_data *data, char *content, int fd) +{ + char *str; + + while (1) + { + str = readline ("> "); + if (!str \ + || (!ft_strncmp (content, str, ft_strlen(content)) && \ + (ft_strlen(content) == (ft_strlen(str))))) + { + free (str); + close (fd); + return ; + } + heredoc_parser(data, fd, str); + } +} + +static void heredoc_parser(t_data *data, int fd, char *str) +{ + int i; + char *tmp; + + i = -1; + tmp = ft_strdup(""); + while (str[++i]) + { + if (str[i] == '$') + { + if (str[i + 1] == '?') + tmp = heredoc_question(data, tmp, &i); + else + tmp = heredoc_expand(data, str, tmp, &i); + } + else + tmp = ft_strncat(tmp, &str[i], 1); + } + write (fd, tmp, ft_strlen(tmp)); + write (fd, "\n", 1); + free (str); +} + +static char *heredoc_question(t_data *data, char *tmp, int *i) +{ + char *temp; + + (void) data; + temp = ft_itoa(g_error_code); + tmp = ft_strncat(tmp, temp, ft_strlen(temp)); + *i += 1; + return (tmp); +} + +static char *heredoc_expand(t_data *data, char *str, char *tmp, int *i) +{ + char *name; + + *i += 1; + name = ft_strdup(""); + while (str[*i] != '\0' && str[*i] != ' ' && str[*i] != '\t') + { + name = ft_strncat(name, &str[*i], 1); + *i += 1; + } + heredoc_replace(data, &tmp, name); + if (str[*i] != '\0') + *i -= 1; + return (tmp); +} + +static void heredoc_replace(t_data *data, char **tmp, char *name) +{ + int j; + t_list *env; + + env = env_search(data, name, TRUE); + if (!env) + { + *tmp = ft_strncat(*tmp, "$", 1); + *tmp = ft_strncat(*tmp, name, ft_strlen(name)); + } + else + { + j = 0; + while (env->env[j] != '=') + j++; + *tmp = ft_strncat(*tmp, \ + &env->env[j + 1], ft_strlen(&env->env[j + 1])); + } +} diff --git a/srcs/redirect/redirect.c b/srcs/redirect/redirect.c new file mode 100644 index 0000000..1e048b5 --- /dev/null +++ b/srcs/redirect/redirect.c @@ -0,0 +1,83 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* redirect.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: kichlee +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/08/13 16:16:07 by eunwolee #+# #+# */ +/* Updated: 2023/08/17 22:04:51 by kichlee ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../../incs/minishell.h" + +int check_redirect(t_leaf *leaf, t_data *data); +static int do_input_redirect(t_leaf *leaf, t_data *data); +static void do_output_redirect(t_leaf *leaf, t_data *data); + +int check_redirect(t_leaf *leaf, t_data *data) +{ + t_leaf *temp; + + temp = leaf->left_child->left_child; + while (temp) + { + if (temp->token->redirect_type == T_INPUT \ + ||temp->token->redirect_type == T_HEREDOC) + { + if (!do_input_redirect(temp, data)) + return (0); + } + else if (temp->token->redirect_type == T_OUTPUT \ + ||temp->token->redirect_type == T_APPEND) + do_output_redirect(temp, data); + temp = temp->left_child; + } + return (1); +} + +static int do_input_redirect(t_leaf *leaf, t_data *data) +{ + int fd; + t_leaf *temp; + + fd = 0; + temp = leaf; + if (temp->token->redirect_type == T_HEREDOC) + { + fd = open (data->info->heredoc_file[data->info->index - 1], \ + O_RDONLY); + dup2 (fd, STDIN_FILENO); + return (1); + } + else if (temp->token->redirect_type == T_INPUT) + fd = open (temp->left_child->token->str, O_RDONLY); + if (!check_file (fd, data)) + return (0); + dup2 (fd, STDIN_FILENO); + close (fd); + return (1); +} + +static void do_output_redirect(t_leaf *leaf, t_data *data) +{ + int fd; + t_leaf *temp; + + fd = 0; + temp = leaf; + if (temp->token->redirect_type == T_APPEND) + { + fd = open(temp->left_child->token->str, \ + O_WRONLY | O_APPEND | O_CREAT, 0644); + } + else if (temp->token->redirect_type == T_OUTPUT) + { + fd = open(temp->left_child->token->str, \ + O_WRONLY | O_TRUNC | O_CREAT, 0644); + } + check_file(fd, data); + dup2(fd, STDOUT_FILENO); + close(fd); +} diff --git a/srcs/signal/signal.c b/srcs/signal/signal.c new file mode 100644 index 0000000..dc80c27 --- /dev/null +++ b/srcs/signal/signal.c @@ -0,0 +1,59 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* signal.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: kichlee +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/07/15 18:40:34 by kichlee #+# #+# */ +/* Updated: 2023/08/17 21:36:26 by kichlee ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../../incs/minishell.h" + +void init_base(int ac); +void handle_sigint(int sig); +void child_handler(int signum); +void sig(void); + +void init_base(int ac) +{ + struct termios termi; + + if (ac != 1) + { + printf("Too many arguments\n"); + exit(1); + } + if (tcgetattr(STDIN_FILENO, &termi) == -1) + exit(1); + termi.c_lflag &= ~(ECHOCTL); + if (tcsetattr(STDIN_FILENO, TCSANOW, &termi) == -1 + || tgetent (NULL, "xterm-256color") == -1) + exit(1); +} + +void handle_sigint(int sig) +{ + g_error_code = 1; + printf("\n"); + rl_on_new_line(); + rl_replace_line("", 0); + rl_redisplay(); + (void)sig; +} + +void child_handler(int signum) +{ + printf("\n"); + exit(EXIT_FAILURE); + ft_putendl_fd("", STDERR_FILENO); + (void)signum; +} + +void sig(void) +{ + signal(SIGINT, handle_sigint); + signal(SIGQUIT, SIG_IGN); +} diff --git a/srcs/utils/env.c b/srcs/utils/env.c index 5f216a9..a897954 100644 --- a/srcs/utils/env.c +++ b/srcs/utils/env.c @@ -3,17 +3,17 @@ /* ::: :::::::: */ /* env.c :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: eunwolee +#+ +:+ +#+ */ +/* By: kichlee +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/07/11 06:38:21 by eunwolee #+# #+# */ -/* Updated: 2023/07/21 08:49:50 by eunwolee ### ########.fr */ +/* Updated: 2023/08/17 18:56:37 by kichlee ### ########.fr */ /* */ /* ************************************************************************** */ #include "../../incs/minishell.h" void env_print(t_data *data); -t_list *env_search(t_data *data, char *key); +t_list *env_search(t_data *data, char *key, t_bool flag); t_bool env_remove(t_data *data, char *key); char **env_to_array(t_data *data); @@ -24,25 +24,36 @@ void env_print(t_data *data) cur = data->envs; while (cur) { - printf("%s\n", cur->env); + if (check_equal(cur->env) == TRUE) + printf("%s\n", cur->env); cur = cur->next; } } -//환경변수 이름에 해당하는 노드를 반환하는 함수입니다 -t_list *env_search(t_data *data, char *key) +t_list *env_search(t_data *data, char *key, t_bool flag) { - char *tmp; + char *env; t_list *cur; + int len; - tmp = ft_strncat(key, "=", 1); + env = ft_strdup(key); + if (flag == TRUE) + env = ft_strncat(env, "=", 1); cur = data->envs; + len = ft_strlen(env); while (cur) { - if (!ft_strncmp(cur->env, tmp, ft_strlen(tmp))) + if (!ft_strncmp(cur->env, env, len)) + { + if (flag == FALSE \ + && (cur->env[len] != '\0' && cur->env[len] != '=')) + break ; + free(env); return (cur); + } cur = cur->next; } + free(env); return (NULL); } @@ -50,18 +61,27 @@ t_bool env_remove(t_data *data, char *key) { t_list *env; - env = env_search(data, key); + env = env_search(data, key, TRUE); if (!env) - return (FALSE); - if (env->pre) + { + env = env_search(data, key, FALSE); + if (!env) + return (FALSE); + } + if (!env->pre) + { + env->next->pre = NULL; data->envs = env->next; + } else + { + env->next->pre = env->pre; env->pre->next = env->next; + } ft_lstdelone(env); return (TRUE); } -//리턴값 더블포인터를 data->env_array에 담아서 사용하시고, 쓰고 나서 더블포인터만 free해주면 됩니다 char **env_to_array(t_data *data) { t_list *cur; @@ -70,9 +90,9 @@ char **env_to_array(t_data *data) int cnt; cnt = ft_lstsize(data->envs); - array = (char **)ft_calloc(cnt, sizeof(char *)); + array = (char **)ft_calloc(cnt + 1, sizeof(char *)); if (!array) - return (NULL); + program_error_exit("bash"); i = -1; cur = data->envs; while (++i < cnt) diff --git a/srcs/utils/error.c b/srcs/utils/error.c new file mode 100644 index 0000000..173b259 --- /dev/null +++ b/srcs/utils/error.c @@ -0,0 +1,104 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* error.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: eunwolee +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/08/17 14:53:39 by eunwolee #+# #+# */ +/* Updated: 2023/08/17 21:29:14 by eunwolee ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../../incs/minishell.h" + +void error_print(char *cmd, char *option, int flag); +void check_errortype(char *str, int flag); +static char *ft_strjoinstr(char *s1, char *s2); + +void error_print(char *cmd, char *option, int flag) +{ + char *tmp; + char *str; + + str = ft_strdup(cmd); + tmp = str; + str = ft_strjoinstr("bash: ", str); + free(tmp); + if (option) + { + tmp = str; + str = ft_strjoin(str, ": "); + free(tmp); + tmp = str; + str = ft_strjoin(str, option); + free(tmp); + } + check_errortype(str, flag); +} + +void check_errortype(char *str, int flag) +{ + char *tmp; + + tmp = str; + if (flag == 0) + str = ft_strjoinstr(str, ": command not found\n"); + else if (flag == 1) + str = ft_strjoinstr(str, ": No such file or directory\n"); + else if (flag == 2) + { + str = ft_strjoinstr(str, ": is a directory\n"); + } + else if (flag == 3) + { + str = "bash: exit: too many arguments\n"; + write(2, str, ft_strlen (str)); + return ; + } + else if (flag == 4) + { + write(2, "bash: exit: ", 12); + str = ft_strjoinstr(str, " numeric argument required\n"); + } + free(tmp); + write(2, str, ft_strlen (str)); + free(str); +} + +static char *ft_strjoinstr(char *s1, char *s2) +{ + char *tmp; + size_t lena; + size_t lenb; + + if (s1 == 0 || s2 == 0) + return (0); + lena = ft_strlen(s1); + lenb = ft_strlen(s2); + tmp = (char *)malloc(sizeof(char) * (lena + lenb + 1)); + if (!tmp) + return (0); + tmp[0] = '\0'; + ft_strlcat(tmp, s1, lena + 1); + ft_strlcat(tmp, s2, lena + lenb + 1); + tmp[lena + lenb] = '\0'; + return (tmp); +} + +t_bool error_back_readline(t_data *data, char *str, int error_code_b, int flag) +{ + (void) data; + if (flag) + perror(str); + else + printf("%s\n", str); + g_error_code = error_code_b; + return (FALSE); +} + +void program_error_exit(char *str) +{ + perror(str); + exit(errno); +} diff --git a/srcs/utils/utils.c b/srcs/utils/free.c similarity index 64% rename from srcs/utils/utils.c rename to srcs/utils/free.c index 5b6eb0c..c1a3e31 100644 --- a/srcs/utils/utils.c +++ b/srcs/utils/free.c @@ -1,51 +1,42 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* utils.c :+: :+: :+: */ +/* free.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: eunwolee +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/07/12 19:40:44 by eunwolee #+# #+# */ -/* Updated: 2023/07/21 08:45:57 by eunwolee ### ########.fr */ +/* Updated: 2023/08/17 14:57:44 by eunwolee ### ########.fr */ /* */ /* ************************************************************************** */ #include "../../incs/minishell.h" -t_bool error_back_readline(t_data *data, char *str, int error_code); -void program_error_exit(char *str); void input_free(t_data *data); void data_free(t_data *data); -//input 관련 에러일 때 사용 -t_bool error_back_readline(t_data *data, char *str, int error_code) -{ - printf("%s\n", str); - data->error_code = error_code; - return (FALSE); -} - -//system 관련 에러일 때 -void program_error_exit(char *str) -{ - perror(str); - exit(errno); -} - -//input 한번 끝났을 때 사용 void input_free(t_data *data) { + int i; + ft_lstclear(&data->tokens); data->tokens = NULL; free(data->input); data->input = NULL; - tree_clear(data->root); + tree_clear(data->root); data->root = NULL; + free(data->pipe->com); + free(data->pipe); + i = -1; + while (++i < data->info->heredoc_flag) + free(data->info->heredoc_file[i]); + free(data->info->heredoc_file); + free(data->info); } -//정상종료 시 사용 void data_free(t_data *data) { + free(data->env_array); ft_lstclear(&data->envs); free(data); -} \ No newline at end of file +} diff --git a/srcs/utils/list.c b/srcs/utils/list.c index f2cb7b4..d35ea5a 100644 --- a/srcs/utils/list.c +++ b/srcs/utils/list.c @@ -6,7 +6,7 @@ /* By: eunwolee +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/07/02 16:53:01 by eunwolee #+# #+# */ -/* Updated: 2023/07/12 19:39:50 by eunwolee ### ########.fr */ +/* Updated: 2023/08/17 12:36:05 by eunwolee ### ########.fr */ /* */ /* ************************************************************************** */ @@ -23,7 +23,7 @@ t_list *ft_lstnew(void) tmp = (t_list *)ft_calloc(1, sizeof(t_list)); if (!tmp) - return (NULL); + program_error_exit("bash"); return (tmp); } diff --git a/srcs/utils/temp.c b/srcs/utils/temp.c deleted file mode 100644 index f6442b2..0000000 --- a/srcs/utils/temp.c +++ /dev/null @@ -1,99 +0,0 @@ -//테스트용 임시 함수들 - -#include "../incs/minishell.h" - -void tree_print(t_leaf *leaf); -void print_token(t_data *data); -void env_array_print(t_data *data); -void check_leak(); - -//트리 전위순회 출력 -void tree_print(t_leaf *leaf) -{ - if (!leaf) - return ; - if (!leaf->parent) - printf("\n\n--------------tree preorder--------------\n"); - if (leaf->token) - { - if (leaf->token->type == T_CMD) - printf("CMD, str: %s\n", leaf->token->str); - else if (leaf->token->type == T_ARG) - printf("ARG, str: %s\n", leaf->token->str); - else if (leaf->token->type == T_REDIRECT) - { - printf("REDIRECT, "); - if (leaf->token->redirect_type == T_INPUT) - printf("type: <\n"); - else if (leaf->token->redirect_type == T_OUTPUT) - printf("type: >\n"); - else if (leaf->token->redirect_type == T_HEREDOC) - printf("type: <<\n"); - else if (leaf->token->redirect_type == T_APPEND) - printf("type: >>\n"); - } - } - else - { - if (leaf->leaf_type == T_PIPE) - printf("\nPIPE, exist: %d\n", leaf->exist); - else - printf("CMD\n"); - } - tree_print(leaf->left_child); - tree_print(leaf->right_child); -} - -//토큰 리스트 출력용 -void print_token(t_data *data) -{ - t_list *tmp = data->tokens; - printf("\n\n--------------token list--------------\n"); - while (tmp) - { - if (tmp->token->type == T_PIPE) - printf("token: pipe\n"); - else if (tmp->token->type == T_REDIRECT) - { - printf("token: redirect, "); - if (tmp->token->redirect_type == T_INPUT) - printf("type: <\n"); - else if (tmp->token->redirect_type == T_OUTPUT) - printf("type: >\n"); - else if (tmp->token->redirect_type == T_HEREDOC) - printf("type: <<\n"); - else if (tmp->token->redirect_type == T_APPEND) - printf("type: >>\n"); - } - else if (tmp->token->type == T_WORD) - { - printf("token: word, "); - printf("str: %s\n", tmp->token->str); - } - else if (tmp->token->type == T_CMD) - { - printf("token: cmd, "); - printf("str: %s\n", tmp->token->str); - } - else if (tmp->token->type == T_ARG) - { - printf("token: arg, "); - printf("str: %s\n", tmp->token->str); - } - tmp = tmp->next; - } -} - -//배열에 넣은 환경변수 출력용 -void env_array_print(t_data *data) -{ - char **array = env_to_array(data); - - for(int i=0; array[i]; i++) - printf("%s\n", array[i]); -} - -void check_leak() -{ - system("leaks minishell"); -} \ No newline at end of file diff --git a/srcs/utils/tree.c b/srcs/utils/tree.c index 15092c9..abb3dac 100644 --- a/srcs/utils/tree.c +++ b/srcs/utils/tree.c @@ -6,11 +6,11 @@ /* By: eunwolee +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/06/29 11:48:39 by eunwolee #+# #+# */ -/* Updated: 2023/07/21 08:36:07 by eunwolee ### ########.fr */ +/* Updated: 2023/08/17 12:36:21 by eunwolee ### ########.fr */ /* */ /* ************************************************************************** */ -#include "../incs/minishell.h" +#include "../../incs/minishell.h" t_leaf *tree_create_leaf(t_leaf *parent, int leaf_type); t_bool tree_add_left(t_leaf *parent, t_token *new_token, int leaf_type); @@ -23,7 +23,7 @@ t_leaf *tree_create_leaf(t_leaf *parent, int leaf_type) new = (t_leaf *)ft_calloc(1, sizeof(t_leaf)); if (!new) - return (NULL); + program_error_exit("bash"); new->leaf_type = leaf_type; new->parent = parent; new->left_child = NULL; @@ -59,12 +59,16 @@ t_bool tree_add_right(t_leaf *parent, t_token *new_token, int leaf_type) return (TRUE); } -//토큰은 환경변수 리스트에서 삭제하기 때문에 트리의 큰 틀만 삭제 void tree_clear(t_leaf *leaf) { + t_leaf *left; + t_leaf *right; + if (!leaf) return ; + left = leaf->left_child; + right = leaf->right_child; free(leaf); - tree_clear(leaf->left_child); - tree_clear(leaf->right_child); + tree_clear(left); + tree_clear(right); }