#include #include "typeutils.h" #include "lex.h" DECLARE_VEC(char*, StrVec) typedef struct { Token* ptr; size_t len; size_t pos; } TokStream; typedef enum { STDIN_REDIR, STDOUT_REDIR_TRUNC, STDOUT_REDIR_APPEND, } RedirKind; typedef struct { RedirKind kind; union { Word std_redir_filename; } as; } Redirect; DECLARE_VEC(Redirect, RedirectVec) typedef struct { WordVec args; RedirectVec redirects; // TODO: prefix variable settings } Command; typedef enum { CONN_PIPE, CONN_EOL, // TODO: add the |& thingy } Connector; typedef struct { Command cmd; Connector conn; } PipelineElement; DECLARE_VEC(PipelineElement, Pipeline) Command parse_command(TokStream* toks) { WordVec args = make_WordVec(256); RedirectVec redirects = make_RedirectVec(256); for ( Token curr_tok; (curr_tok = toks->ptr[toks->pos], !(curr_tok.kind == TOK_SPECIAL && (curr_tok.as.spec == PIPE && curr_tok.as.spec == EOL))); toks->pos++ ) { if (curr_tok.kind == TOK_SPECIAL) { Token tok; switch (curr_tok.as.spec) { case WRITE_REDIR_TRUNC: toks->pos++; tok = toks->ptr[toks->pos]; if(tok.kind != TOK_WORD) exit(1); push_to_RedirectVec(&redirects, (Redirect){.kind = STDOUT_REDIR_TRUNC, .as.std_redir_filename = tok.as.word}); break; case WRITE_REDIR_APPEND: toks->pos++; tok = toks->ptr[toks->pos]; if(tok.kind != TOK_WORD) exit(1); push_to_RedirectVec(&redirects, (Redirect){.kind = STDOUT_REDIR_APPEND, .as.std_redir_filename = tok.as.word}); break; case READ_REDIR: toks->pos++; tok = toks->ptr[toks->pos]; if(tok.kind != TOK_WORD) exit(1); push_to_RedirectVec(&redirects, (Redirect){.kind = STDOUT_REDIR_APPEND, .as.std_redir_filename = tok.as.word}); break; default: exit(69); } } else if (curr_tok.kind == TOK_WORD){ push_to_WordVec(&args, curr_tok.as.word); } } return (Command){.args = args, .redirects = redirects}; } Pipeline parse_tokstream(TokenVec toks) { TokStream tokstream = {.ptr = toks.items, .len = toks.count, .pos = 0}; Pipeline result = make_Pipeline(256); }