summaryrefslogtreecommitdiff
path: root/42sh/src/parser/parser_redir.c
diff options
context:
space:
mode:
Diffstat (limited to '42sh/src/parser/parser_redir.c')
-rw-r--r--42sh/src/parser/parser_redir.c59
1 files changed, 59 insertions, 0 deletions
diff --git a/42sh/src/parser/parser_redir.c b/42sh/src/parser/parser_redir.c
new file mode 100644
index 0000000..9a06d0b
--- /dev/null
+++ b/42sh/src/parser/parser_redir.c
@@ -0,0 +1,59 @@
+#include <err.h>
+
+#include "parser_functions.h"
+#include "parser_utils.h"
+
+struct ast *parse_redirection(struct lexer *lexer, enum parser_state *state)
+{
+ // The caller (prefix grammar in this case) will have to attach its
+ // own ast as the left child of the redir ast
+ struct ast *redir = ast_create(AST_REDIRECTION);
+ if (redir == NULL)
+ {
+ QUICK_CLEANUP
+ }
+
+ struct token next = lexer_peek(lexer);
+
+ union ast_caster cast;
+ cast.ast = redir;
+
+ if (next.type == TOKEN_IONUMBER)
+ {
+ cast.ast_r->redirect.fd = next.value;
+ lexer_pop(lexer);
+ next = lexer_peek(lexer);
+ }
+ else
+ {
+ cast.ast_r->redirect.fd = string_create("1");
+ }
+
+ if (next.type != TOKEN_REDIR)
+ {
+ cleanup(redir, state);
+ return NULL;
+ }
+
+ cast.ast_r->redirect.redir = next.value;
+ if (next.value->data[0] == '<' && cast.ast_r->redirect.fd->data[0] == '1')
+ {
+ cast.ast_r->redirect.fd->data[0] = '0';
+ }
+
+ lexer_pop(lexer);
+ next = lexer_peek(lexer);
+
+ if (!(ISWORD(next.type)))
+ {
+ cleanup(redir, state);
+ errx(2, "redir: bad grammar (bad redir).");
+ }
+
+ litteral_reserved_word(&next);
+ cast.ast_r->redirect.file = next.value;
+ lexer_pop(lexer);
+
+ ((struct ast_redirection *)redir)->redirect = cast.ast_r->redirect;
+ return redir;
+}