summaryrefslogtreecommitdiff
path: root/42sh/src/parser/parser_redir.c
blob: 9a06d0b647f6e0c1f5d99eea4e7866d378962ca0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
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;
}