Implement exitable skeleton of a shell
authorLukas Jiriste <ljiriste@student.42prague.com>
Fri, 26 Apr 2024 12:03:25 +0000 (14:03 +0200)
committerLukas Jiriste <ljiriste@student.42prague.com>
Fri, 26 Apr 2024 12:18:09 +0000 (14:18 +0200)
The minishell is now able to accept input and access history through
the GNU Readline library.
The minishell itself prints prompt with currect directory.
It also handles the "exit" command as well as ctrl-D
so that it can exit. It prints "exit" on exit like bash.

Makefile
src/main.c

index 7204d114069df563819484337453699ad7b4d28d..9166aa6cfdf2a2d4fda0b605b880da41253936de 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -3,6 +3,9 @@ CFLAGS = -std=c99 -Wall -Wextra -Werror -Wpedantic
 
 RM := rm -f
 
+EXT_LIBS := readline
+LINKS := $(addprefix -l, $(EXT_LIBS))
+
 SUBPROJECTS := Libft
 
 INCDIR := inc
@@ -25,7 +28,7 @@ debug : CFLAGS += -g
 debug : $(NAME)
 
 $(NAME) : $(OBJECTS) Libft/libft.a
-       $(CC) $(CFLAGS) -o $@ $^
+       $(CC) $(CFLAGS) -o $@ $^ $(LINKS)
 
 Libft/libft.a : | Libft/Makefile
 ifneq (,$(findstring debug, $(MAKECMDGOALS)))
index c4af877afa86e87b2e36b9588fe655056a47d947..59d0bf713f8c369fc803bdb872a6ef50182f635a 100644 (file)
@@ -6,11 +6,69 @@
 /*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/04/26 13:11:47 by ljiriste          #+#    #+#             */
-/*   Updated: 2024/04/26 13:12:09 by ljiriste         ###   ########.fr       */
+/*   Updated: 2024/04/26 14:13:15 by ljiriste         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
+#include "libft.h"
+#include <stdlib.h>
+#include <unistd.h>                            // getcwd
+#include <stdio.h>                             // readline
+#include <readline/readline.h> // readline
+#include <readline/history.h>  // readline
+
+// A string is "almost_empty" if it:
+//             is a NULL pointer
+//             is an empty string
+//             only contains whitespace
+int    almost_empty(const char *str)
+{
+       if (!str)
+               return (1);
+       while (*str)
+       {
+               if (!ft_isspace(*str))
+                       return (0);
+               ++str;
+       }
+       return (1);
+}
+
+char   *rl_get_line(void)
+{
+       char    *cwd;
+       char    *prompt;
+       char    *line;
+
+       cwd = getcwd(NULL, 0);
+       prompt = ft_strjoin(cwd, "$ ");
+       free(cwd);
+       line = readline(prompt);
+       free(prompt);
+       if (!almost_empty(line))
+               add_history(line);
+       return (line);
+}
+
+void   handle_input(__attribute__((unused)) const char *input)
+{
+       return ;
+}
+
 int main(void)
 {
-       return (0);
+       char    *line;
+
+       while (1)
+       {
+               line = rl_get_line();
+               if (!line || !ft_strcmp(line, "exit"))
+               {
+                       rl_clear_history();
+                       ft_printf("exit\n");
+                       return (0);
+               }
+               handle_input(line);
+               free(line);
+       }
 }