maxishell
Implementation of a shell for Linux-like systems
Loading...
Searching...
No Matches
tokeniser.c
Go to the documentation of this file.
1/* ************************************************************************** */
2/* */
3/* ::: :::::::: */
4/* tokeniser.c :+: :+: :+: */
5/* +:+ +:+ +:+ */
6/* By: rocky <marvin@42.fr> +#+ +:+ +#+ */
7/* +#+#+#+#+#+ +#+ */
8/* Created: 2024/06/12 15:00:23 by rocky #+# #+# */
9/* Updated: 2024/09/09 15:48:26 by dmdemirk ### ########.fr */
10/* */
11/* ************************************************************************** */
12
13#include "tokens.h"
14#include <string.h>
15
16t_token *tokenise(char *str);
17char *handle_special_chars(char *str, t_token **tokens);
18t_token *new_token(char *value, t_token_type type);
19void append_token(t_token **tokens, t_token *new_token);
20char *handle_phrase(char *str, t_token **tokens);
21
22t_token *tokenise(char *str)
23{
24 t_token *tokens;
25
26 tokens = NULL;
27 while (*str)
28 {
29 while (*str && ft_strchr(" \t\n\r\v\f", *str) != NULL)
30 str++;
31 if (ft_strchr("<|>", *str) != NULL)
32 str = handle_special_chars(str, &tokens);
33 else
34 str = handle_phrase(str, &tokens);
35 }
36 return (tokens);
37}
38
39char *handle_special_chars(char *str, t_token **tokens)
40{
41 if (*str == '<')
42 {
43 if (*(str + 1) == '<')
44 {
45 append_token(tokens, new_token("<<", REDIR_HEREDOC));
46 (str)++;
47 }
48 else
49 append_token(tokens, new_token("<", REDIR_IN));
50 }
51 else if (*str == '>')
52 {
53 if (*(str + 1) == '>')
54 {
55 append_token(tokens, new_token(">>", REDIR_APPEND));
56 (str)++;
57 }
58 else
59 append_token(tokens, new_token(">", REDIR_OUT));
60 }
61 else if (*str == '|')
62 append_token(tokens, new_token("|", PIPE));
63 (str)++;
64 return (str);
65}
66
67t_token *new_token(char *value, t_token_type type)
68{
69 t_token *token;
70
71 token = malloc(sizeof(t_token));
72 if (!token)
73 return (NULL);
74 token->data = ft_strdup(value);
75 if (!token->data)
76 {
77 free(token);
78 return (NULL);
79 }
80 token->type = type;
81 token->next = NULL;
82 return (token);
83}
84
86{
87 t_token *curr;
88
89 if (!*tokens)
90 *tokens = new_token;
91 else
92 {
93 curr = *tokens;
94 while (curr->next)
95 curr = curr->next;
96 curr->next = new_token;
97 }
98}
99
100char *handle_phrase(char *str, t_token **tokens)
101{
102 char *start;
103 char quote_flag;
104 char quote_type;
105
106 start = str;
107 quote_flag = 0;
108 quote_type = 0;
109 while (*str)
110 {
111 if (!quote_flag && (*str == '\'' || *str == '\"'))
112 {
113 quote_flag = 1;
114 quote_type = *str;
115 }
116 else if (quote_flag && *str == quote_type)
117 quote_flag = 0;
118 if (!quote_flag && ft_strchr(" \t\n\r\v\f<|>", *str) != NULL)
119 break ;
120 str++;
121 }
122 append_word_if_valid(start, str, tokens);
123 return (str);
124}
char * ft_strchr(const char *s, int c)
Definition ft_strchr.c:25
char * ft_strdup(const char *s)
Definition ft_strdup.c:23
t_token_type type
Definition tokens.h:43
struct s_token * next
Definition tokens.h:45
char * data
Definition tokens.h:44
t_token * new_token(char *value, t_token_type type)
Definition tokeniser.c:67
char * handle_phrase(char *str, t_token **tokens)
Definition tokeniser.c:100
t_token * tokenise(char *str)
Definition tokeniser.c:22
void append_token(t_token **tokens, t_token *new_token)
Definition tokeniser.c:85
char * handle_special_chars(char *str, t_token **tokens)
Definition tokeniser.c:39
@ REDIR_IN
Definition tokens.h:34
@ REDIR_HEREDOC
Definition tokens.h:37
@ PIPE
Definition tokens.h:32
@ REDIR_OUT
Definition tokens.h:35
@ REDIR_APPEND
Definition tokens.h:36
void append_word_if_valid(char *start, char *str, t_token **tokens)
enum e_token_type t_token_type