MiniDevil As beautiful as a shell
main.c
Go to the documentation of this file.
1 /* ************************************************************************** */
2 /* */
3 /* ::: :::::::: */
4 /* main.c :+: :+: :+: */
5 /* +:+ +:+ +:+ */
6 /* By: baelgadi <baelgadi@student.42.fr> +#+ +:+ +#+ */
7 /* +#+#+#+#+#+ +#+ */
8 /* Created: 2025/12/02 16:01:39 by zotaj-di #+# #+# */
9 /* Updated: 2026/03/04 04:32:33 by baelgadi ### ########.fr */
10 /* */
11 /* ************************************************************************** */
12 
13 #include <readline/readline.h>
14 #include <readline/history.h>
15 #include "libft.h"
16 #include "get_next_line.h"
17 #include "signals.h"
18 #include "token.h"
19 #include "parser.h"
20 #include "ast.h"
21 #include "executor.h"
22 #include "env.h"
23 #include "minishell_ui.h"
24 
35 static int process_input(char *input, t_shell *shell)
36 {
37  t_token *tokens;
38  t_ast *ast;
39  int status;
40 
41  tokens = tokenize(input);
42  if (!tokens)
43  return (2);
44  if (expand_all_tokens(tokens, shell) < 0)
45  {
46  free_token_list(tokens);
47  return (1);
48  }
49  ast = parse(tokens);
50  free_token_list(tokens);
51  if (!ast)
52  return (2);
53  shell->current_ast = ast;
54  if (collect_heredocs(ast, shell) == -1)
55  status = 128 + SIGINT;
56  else
57  status = executor(ast, shell);
58  free_ast(ast);
59  shell->current_ast = NULL;
60  return (status);
61 }
62 
72 static char *read_input(t_shell *shell)
73 {
74  char *line;
75  int len;
76 
77  if (shell->interactive)
78  return (readline("MiniDevil $> "));
79  line = get_next_line(STDIN_FILENO);
80  if (line)
81  {
82  len = ft_strlen(line);
83  if (len > 0 && line[len - 1] == '\n')
84  line[len - 1] = '\0';
85  }
86  return (line);
87 }
88 
98 static void handle_input(char *input, t_shell *shell)
99 {
100  int i;
101 
102  if (!input || input[0] == '\0')
103  return ;
104  i = 0;
105  while (input[i] && ft_isspace(input[i]))
106  i++;
107  if (input[i] == '\0')
108  return ;
109  if (shell->interactive)
110  add_history(input);
111  shell->exit_status = process_input(input, shell);
112 }
113 
123 static void main_loop(t_shell *shell)
124 {
125  char *input;
126 
127  shell->running = 1;
128  while (shell->running)
129  {
130  if (shell->interactive)
132  g_signal = 0;
133  input = read_input(shell);
134  if (!input && shell->interactive)
135  ft_putstr_fd("exit\n", STDOUT_FILENO);
136  if (!input)
137  break ;
138  if (g_signal == SIGINT)
139  {
140  shell->exit_status = 130;
141  g_signal = 0;
142  }
144  shell->current_input = input;
145  handle_input(input, shell);
146  free(input);
147  shell->current_input = NULL;
148  }
149 }
150 
163 int main(int ac, char **av, char **envp)
164 {
165  t_shell shell;
166 
167  ft_memset(&shell, 0, sizeof(t_shell));
168  shell.env = init_env(envp);
169  shell.exit_status = 0;
170  shell.interactive = (isatty(STDIN_FILENO) && isatty(STDOUT_FILENO));
171  shell.ui_mode = 0;
172  shell.is_child = 0;
173  shell.ui = NULL;
174  if (ac > 1 && ft_strncasecmp(av[1], "--ui", 5) == 0)
175  run_ui_mode(&shell);
176  else
177  {
178  (void)ac;
179  (void)av;
180  main_loop(&shell);
181  }
182  free_env_list(&shell.env);
183  get_next_line(-42);
184  return (shell.exit_status);
185 }
AST node creation and destruction prototypes.
void free_ast(t_ast *node)
Recursively free an entire AST tree.
Definition: ast_utils.c:46
Environment variable management prototypes.
t_env * init_env(char **envp)
Initialize the environment linked list from main()'s envp.
Definition: env_init.c:27
void free_env_list(t_env **env_list)
Free all nodes in the env linked list.
Definition: env_utils.c:69
int executor(t_ast *node, t_shell *shell)
Main AST executor that dispatches by node type.
Definition: executor.c:42
Executor prototypes for commands, pipes, redirections & heredocs.
int expand_all_tokens(t_token *tokens, t_shell *shell)
Expand all token values before parsing.
Definition: expander.c:150
int collect_heredocs(t_ast *node, t_shell *shell)
Pre collect all heredocs in the AST before the execution phase.
static char * read_input(t_shell *shell)
Read 1 line of input from the user.
Definition: main.c:72
static int process_input(char *input, t_shell *shell)
tokenize -> expand -> parse -> execute
Definition: main.c:35
static void main_loop(t_shell *shell)
Main REPL (standard mode)
Definition: main.c:123
static void handle_input(char *input, t_shell *shell)
Filter and dispatch input to processing.
Definition: main.c:98
int main(int ac, char **av, char **envp)
Entry point.
Definition: main.c:163
UI mode structures, macros & function prototypes.
t_ast * parse(t_token *tokens)
Parse a token list into an AST.
Definition: parser.c:26
Parser entry point & sub parser prototypes.
volatile sig_atomic_t g_signal
The single global variable.
Definition: signals.c:17
void setup_execution_signals(void)
Ignore signals during command execution in the parent.
Definition: signals.c:83
void setup_interactive_signals(void)
Configure signals for the interactive prompt.
Definition: signals.c:43
Signal handler prototypes.
AST node (union based ↑)
Definition: structs.h:151
Shell state.
Definition: structs.h:164
int interactive
1 if STDIN is a tty
Definition: structs.h:168
t_env * env
Environment linked list.
Definition: structs.h:165
int is_child
Child flag (to avoid leaks)
Definition: structs.h:173
int running
1 while main loop is active
Definition: structs.h:167
char * current_input
Current input line.
Definition: structs.h:172
int exit_status
Last command's exit status.
Definition: structs.h:166
struct s_ast * current_ast
Currently executing AST.
Definition: structs.h:171
struct s_ui * ui
UI state (NULL if off)
Definition: structs.h:170
int ui_mode
1 if UI mode (–ui)
Definition: structs.h:169
Lexer token (singly linked list)
Definition: structs.h:71
void free_token_list(t_token *head)
Free the entire token linked list.
Definition: token.c:64
Lexer, tokenizer, expander, and quote handling prototypes.
t_token * tokenize(char *input)
Tokenize the input string into a linked list of tokens.
Definition: tokenizer.c:144
void run_ui_mode(t_shell *shell)
Entry point for UI mode.
Definition: ui_main.c:91