diff options
| -rw-r--r-- | src/exec.c | 6 | ||||
| -rw-r--r-- | src/lexparse.c | 32 | ||||
| -rw-r--r-- | src/main.c | 9 | ||||
| -rw-r--r-- | src/preproc.c | 36 | ||||
| -rw-r--r-- | src/stages.h | 6 | ||||
| -rw-r--r-- | src/syntax.h | 2 |
6 files changed, 70 insertions, 21 deletions
@@ -36,7 +36,7 @@ void source_script(char* fname, ShellState* shstate) { while (getline(&line, &len, fp) != -1) { line[strcspn(line, "\r\n")] = '\0'; - execute_line(line, shstate); + execute_string_line(line, shstate); } free(line); fclose(fp); @@ -265,9 +265,9 @@ void execute_command_pipeline(Pipeline pipeline, int stdin_fd, int stdout_fd, bo } } -void execute_pipeline_tree(PipelineTree pltree, ShellState* shstate) { +void execute_pipeline_tree(Pipeline root_pl, ShellState* shstate, int stdin_fd, int stdout_fd) { int pgid = -1; signal(SIGTTIN, SIG_IGN); signal(SIGTTOU, SIG_IGN); - execute_command_pipeline(*pltree.root, STDIN_FILENO, STDOUT_FILENO, true, &pgid, shstate); + execute_command_pipeline(root_pl, stdin_fd, stdout_fd, true, &pgid, shstate); } diff --git a/src/lexparse.c b/src/lexparse.c index eae5c16..2fcd909 100644 --- a/src/lexparse.c +++ b/src/lexparse.c @@ -16,6 +16,9 @@ typedef struct { DECLARE_MAYBE(Token, MaybeToken) +TokenVec* lex_level(char* line, size_t* pos, char until, TokenVecVec* tok_seq_pool); + + MaybeToken consolidate_buffer(LexingBuffer* buf) { if (buf->lit_germ.count > 0) { push_to_Word(&buf->word_germ, (Chunk){ @@ -40,11 +43,26 @@ MaybeToken consolidate_buffer(LexingBuffer* buf) { } -static MaybeChunk handle_dollar_expansion(char* line, size_t* pos, QuotationMode qmode) { +static MaybeChunk handle_dollar_expansion(char* line, size_t* pos, QuotationMode qmode, TokenVecVec* tok_seq_pool) { (*pos)++; if (line[*pos] == '(') { - // TODO - exit(66); + (*pos)++; + if (line[*pos] == '(') { + // TODO: arithm parsing + exit(66); + } else { + TokenVec* sub_region = lex_level(line, pos, ')', tok_seq_pool); + (*pos)++; // consume paren + return (MaybeChunk){ + .some = true, + .value = (Chunk){ + .qmode = qmode, + .kind = CHUNK_CMDSUB, + .as.cmdsub_toks = sub_region, + } + }; + } + } else if (line[*pos] == '_' || isalnum(line[*pos])){ String buf = make_String(256); while (line[*pos] == '_' || isalnum(line[*pos])) { @@ -96,7 +114,7 @@ static Chunk collect_single_q_section(char* line, size_t* pos) { }; } -static void collect_double_q_section(char* line, Word* result_buf, size_t* pos) { +static void collect_double_q_section(char* line, Word* result_buf, size_t* pos, TokenVecVec* tok_seq_pool) { // TODO: add the extra double-q expansions (*pos)++; String lit_buf = make_String(256); @@ -104,7 +122,7 @@ static void collect_double_q_section(char* line, Word* result_buf, size_t* pos) while (line[*pos] != '\"' && line[*pos] != '\0') { // TODO: handle escapes if (line[*pos] == '$') { - MaybeChunk m_dollar = handle_dollar_expansion(line, pos, DOUBLE_Q); + MaybeChunk m_dollar = handle_dollar_expansion(line, pos, DOUBLE_Q, tok_seq_pool); if (m_dollar.some) { if (lit_buf.count>0) { push_to_Word(result_buf, (Chunk){.qmode = DOUBLE_Q, .kind = CHUNK_LIT, .as.lit_str = inner(&lit_buf)}); @@ -211,9 +229,9 @@ TokenVec* lex_level(char* line, size_t* pos, char until, TokenVecVec* tok_seq_po Chunk chunk = collect_single_q_section(line, pos); push_to_Word(&buf.word_germ, chunk); } else if (line[*pos] == '\"') { - collect_double_q_section(line, &buf.word_germ,pos); + collect_double_q_section(line, &buf.word_germ,pos, tok_seq_pool); } else if (line[*pos] == '$') { - MaybeChunk dollar_chunk = handle_dollar_expansion(line, pos, UN_Q); + MaybeChunk dollar_chunk = handle_dollar_expansion(line, pos, UN_Q, tok_seq_pool); if (dollar_chunk.some) { push_to_Word(&buf.word_germ, dollar_chunk.value); } else { @@ -1,4 +1,5 @@ #include <stdlib.h> +#include <unistd.h> #include <stdio.h> #include <readline/readline.h> #include <readline/history.h> @@ -10,10 +11,10 @@ #include "utils.h" -void execute_line(char *line, ShellState *shstate) { +void execute_string_line(char *line, ShellState *shstate) { Ast ast = lex(line); - PipelineTree pltree = process_ast(ast, shstate); - execute_pipeline_tree(pltree, shstate); + PipelineTree pltree = process_ast(*ast.root, shstate); + execute_pipeline_tree(*pltree.root, shstate, STDIN_FILENO, STDOUT_FILENO); } @@ -25,7 +26,7 @@ int main() { line = readline("$ "); if (line[0] == '\0') continue; add_history(line); - execute_line(line, &shstate); + execute_string_line(line, &shstate); } free(line); } diff --git a/src/preproc.c b/src/preproc.c index 8865968..9c26c5f 100644 --- a/src/preproc.c +++ b/src/preproc.c @@ -1,7 +1,11 @@ #include <assert.h> #include <stdio.h> +#include <unistd.h> +#include <stdlib.h> + #include "syntax.h" #include "utils.h" +#include "stages.h" typedef struct { @@ -35,6 +39,28 @@ void split_str_on_space(char* str, StrVec* result) { } +char* get_cmdsub_output(TokenVec sub_region, ShellState* shstate) { + int pipe_fds[2]; + pipe(pipe_fds); + + PipelineTree sub_tree = process_ast(sub_region, shstate); + // TODO: tree cleanup + + execute_pipeline_tree(*sub_tree.root, shstate, STDIN_FILENO, pipe_fds[1]); + + String output_buf = make_String(256); + + char str_buf[256]; + ssize_t len; + while ((len = read(pipe_fds[0], str_buf, sizeof(str_buf))) > 0) { + append_str_to_String(&output_buf, str_buf); + } + close(pipe_fds[0]); + close(pipe_fds[1]); + return inner(&output_buf); +} + + void process_chunk(Chunk chunk, SplitBuilder* builder, ShellState* shstate) { assert(!(chunk.qmode == SINGLE_Q && chunk.kind != CHUNK_LIT)); @@ -46,6 +72,9 @@ void process_chunk(Chunk chunk, SplitBuilder* builder, ShellState* shstate) { case CHUNK_VAR: chunk_str = get_var(chunk.as.varname, shstate); break; + case CHUNK_CMDSUB: + chunk_str = get_cmdsub_output(*(TokenVec*)chunk.as.cmdsub_toks, shstate); + break; default: exit(77); } @@ -146,7 +175,7 @@ Pipeline* process_token_sequence(TokenVec tokens, PipelineVec* pl_pool, ShellSta case OP_REDIR_W_TRUNC: next_tok = *get_from_ExpandedTokenVec(&exp_tokens, ++i); assert(next_tok.kind == TOK_WORD); - rd = (Redirect){.kind = REDIR_WRITE_TRUNC, .as.filename = next_tok.as.word}; + rd = (Redirect){.kind = REDIR_WRITE_TRUNC, .as.filename = next_tok.as.word}; push_to_RedirectVec(&curr_cmd.redirects, rd); break; default: @@ -168,8 +197,9 @@ Pipeline* process_token_sequence(TokenVec tokens, PipelineVec* pl_pool, ShellSta } -PipelineTree process_ast(Ast ast, ShellState* shstate) { +PipelineTree process_ast(TokenVec root, ShellState* shstate) { PipelineVec pls = make_PipelineVec(256); - Pipeline* root_pl = process_token_sequence(*ast.root, &pls, shstate); + Pipeline* root_pl = process_token_sequence(root, &pls, shstate); return (PipelineTree){.pl_pool = pls, root_pl}; + // TODO: ast cleanup } diff --git a/src/stages.h b/src/stages.h index e731533..6bcdd51 100644 --- a/src/stages.h +++ b/src/stages.h @@ -4,7 +4,7 @@ #include "utils.h" Ast lex(char* input); -PipelineTree process_ast(Ast ast, ShellState* shstate); -void execute_pipeline_tree(PipelineTree pltree, ShellState* shstate); +PipelineTree process_ast(TokenVec root, ShellState* shstate); +void execute_pipeline_tree(Pipeline root_pl, ShellState* shstate, int stdin_fd, int stdout_fd); void source_script(char* fname, ShellState* shstate); -void execute_line(char* line, ShellState* shstate); +void execute_string_line(char* line, ShellState* shstate); diff --git a/src/syntax.h b/src/syntax.h index 9b34818..80ab067 100644 --- a/src/syntax.h +++ b/src/syntax.h @@ -61,7 +61,7 @@ typedef struct { char* lit_str; char* varname; ArithmAst arithm_expr; - // TODO: CHUNK_CMDSUB + void* cmdsub_toks; // NOTE: TokenVec } as; } Chunk; |
