diff options
| author | Ákos Kőrösi <korakos99@gmail.com> | 2026-05-21 12:44:01 +0200 |
|---|---|---|
| committer | Ákos Kőrösi <korakos99@gmail.com> | 2026-05-21 12:44:01 +0200 |
| commit | fc27548c447ed9bcd07493983431e0a6e72c7cef (patch) | |
| tree | dbb25a8cc09cbacd8d0d1dcd4a3962f468f96551 /redes | |
| parent | 2efe642849cf6d45d5413cd77d8cafaf9b32db00 (diff) | |
restructure dir
Diffstat (limited to 'redes')
| -rw-r--r-- | redes/exec.c | 147 | ||||
| -rw-r--r-- | redes/lexparse.c | 229 | ||||
| -rw-r--r-- | redes/main.c | 23 | ||||
| -rw-r--r-- | redes/preproc.c | 135 | ||||
| -rw-r--r-- | redes/stages.h | 7 | ||||
| -rw-r--r-- | redes/syntax.h | 194 |
6 files changed, 0 insertions, 735 deletions
diff --git a/redes/exec.c b/redes/exec.c deleted file mode 100644 index afdf140..0000000 --- a/redes/exec.c +++ /dev/null @@ -1,147 +0,0 @@ -#include <stdio.h> -#include <unistd.h> -#include <fcntl.h> -#include <signal.h> -#include <sys/wait.h> - -#include "syntax.h" - - -void execute_cmd(ExecutableCommand cmd, int* pgid) { - - pid_t pid = fork(); - - if (pid == 0) { - - if (*pgid == -1) { - setpgid(0, 0); - } else { - setpgid(0, *pgid); - } - - dup2(cmd.stdin_fd, STDIN_FILENO); - dup2(cmd.stdout_fd, STDOUT_FILENO); - - for (int i = 0; i < cmd.redirects.count; i++) { - FdRedirect fd_rd = *get_from_FdRedirectVec(&cmd.redirects, i); - dup2(fd_rd.to, fd_rd.redirected); - } - - for (int j = 0; j < cmd.open_fds.count; j++) { - int fd = *get_from_IntVec(&cmd.open_fds, j); - close(fd); - } - - signal(SIGINT, SIG_DFL); - signal(SIGQUIT, SIG_DFL); - signal(SIGTSTP, SIG_DFL); - signal(SIGTTIN, SIG_DFL); - signal(SIGTTOU, SIG_DFL); - - execvp(cmd.args[0], cmd.args); - exit(67); - } - - if (*pgid == -1) { - setpgid(pid, pid); - *pgid = pid; - } else { - setpgid(pid, *pgid); - } -} - - -ExecutableCommand process_pl_command(PlCommand pl_cmd) { - StrVec arg_vec = make_StrVec(256); - for (int i = 0; i < pl_cmd.args.count; i++) { - Arg arg = *get_from_ArgVec(&pl_cmd.args, i); - switch (arg.kind) { - case ARG_LIT: - push_to_StrVec(&arg_vec, arg.as.lit_str); - break; - default: - exit(67); - } - } - - FdRedirectVec fd_redirs = make_FdRedirectVec(256); - IntVec open_fds = make_IntVec(256); - for (int j = 0; j < pl_cmd.redirects.count; j++) { - Redirect redir = *get_from_RedirectVec(&pl_cmd.redirects, j); - FdRedirect fd_redir; - int fd; - switch (redir.kind) { - case REDIR_READ: - fd = open(redir.as.filename, O_RDONLY, 0644); - push_to_IntVec(&open_fds, fd); - fd_redir = (FdRedirect){.to = fd, .redirected = STDIN_FILENO}; - break; - case REDIR_WRITE_APPEND: - fd = open(redir.as.filename, O_WRONLY | O_CREAT | O_APPEND, 0644); - push_to_IntVec(&open_fds, fd); - fd_redir = (FdRedirect){.to = fd, .redirected = STDOUT_FILENO}; - break; - case REDIR_WRITE_TRUNC: - fd = open(redir.as.filename, O_WRONLY | O_CREAT | O_TRUNC, 0644); - push_to_IntVec(&open_fds, fd); - fd_redir = (FdRedirect){.to = fd, .redirected = STDOUT_FILENO}; - break; - default: - exit(67); - } - push_to_FdRedirectVec(&fd_redirs, fd_redir); -} - - char** args = malloc(sizeof(char*) * (arg_vec.count + 1)); - for (int i = 0; i < arg_vec.count; i++) { - args[i] = *get_from_StrVec(&arg_vec, i); - } - args[arg_vec.count] = NULL; - - return (ExecutableCommand){.args = args, .redirects = fd_redirs, .open_fds = open_fds}; -} - - -void execute_command_pipeline(Pipeline pipeline) { - int trunk_fd = STDIN_FILENO; - int pgid = -1; - - - signal(SIGTTIN, SIG_IGN); - signal(SIGTTOU, SIG_IGN); - - for (int i = 0; i < pipeline.count; i++) { - PlCommand cmd = *get_from_Pipeline(&pipeline, i); - ExecutableCommand exec_cmd = process_pl_command(cmd); - - exec_cmd.stdin_fd = trunk_fd; - if (i > 0) { - push_to_IntVec(&exec_cmd.open_fds, trunk_fd); - } - - exec_cmd.stdout_fd = STDOUT_FILENO; - - if (cmd.conn == CONN_PIPE) { - int pipe_fds[2]; - pipe(pipe_fds); - exec_cmd.stdout_fd = pipe_fds[1]; - push_to_IntVec(&exec_cmd.open_fds, pipe_fds[1]); - trunk_fd = pipe_fds[0]; - } - - execute_cmd(exec_cmd, &pgid); - - for (int j = 0; j < exec_cmd.open_fds.count; j++) { - int fd = *get_from_IntVec(&exec_cmd.open_fds, j); - close(fd); - } - } - - tcsetpgrp(STDIN_FILENO, pgid); - while (waitpid(-pgid, NULL, 0) > 0); - tcsetpgrp(STDIN_FILENO, getpgrp()); -} - -void execute_pipeline_tree(PipelineTree pltree) { - execute_command_pipeline(*pltree.root); -} diff --git a/redes/lexparse.c b/redes/lexparse.c deleted file mode 100644 index 3a55b33..0000000 --- a/redes/lexparse.c +++ /dev/null @@ -1,229 +0,0 @@ -#include <ctype.h> -#include "syntax.h" -#include "../src/utils.h" - -typedef struct { - Word word_germ; - String lit_germ; -} LexingBuffer; - -typedef struct { - TokenVec* token_pool; - TokenPtrVec* top_tokens; -} PseudoAst; - -DECLARE_MAYBE(Token, MaybeToken) - -MaybeToken consolidate_buffer(LexingBuffer* buf) { - if (buf->lit_germ.count > 0) { - push_to_Word(&buf->word_germ, (Chunk){ - .qmode = UN_Q, - .kind = CHUNK_LIT, - .as.lit_str = inner(&buf->lit_germ) - }); - buf->lit_germ = make_String(256); - } - if (buf->word_germ.count > 0) { - Word word_germ = buf->word_germ; - buf->word_germ = make_Word(256); - return (MaybeToken){ - .some = true, - .value = (Token){ - .kind = TOK_WORD, - .as.word = word_germ - } - }; - } - return (MaybeToken){.some = false}; -} - - -static Chunk collect_un_q_literal(char* line, size_t* pos) { - String buf = make_String(256); - size_t i; - for (i = *pos; line[*pos] != '$' && line[*pos] != '\0' && line[*pos] == ' '; i++) { - push_to_String(&buf, line[*pos]); - } - *pos = i; - return (Chunk){ - .qmode = UN_Q, - .kind = CHUNK_LIT, - .as.lit_str = inner(&buf), - }; -} - - -static Chunk collect_single_q_section(char* line, size_t* pos) { - (*pos)++; - String buf = make_String(256); - size_t i; - for (i = *pos; line[*pos] != '\'' && line[*pos] != '\0'; i++) { - push_to_String(&buf, line[*pos]); - } - if (line[i] == '\0') exit(44); - - *pos = ++i; - return (Chunk){ - .qmode = SINGLE_Q, - .kind = CHUNK_LIT, - .as.lit_str = inner(&buf) - }; -} - -static Chunk collect_double_q_section(char* line, size_t* pos) { - // TODO: add the extra double-q expansions - (*pos)++; - String buf = make_String(256); - size_t i; - for (i = *pos; line[*pos] != '\'' && line[*pos] != '\0'; i++) { - push_to_String(&buf, line[*pos]); - } - if (line[i] == '\0') exit(44); - - *pos = ++i; - return (Chunk){ - .qmode = DOUBLE_Q, - .kind = CHUNK_LIT, - .as.lit_str = inner(&buf) - }; -} - -DECLARE_MAYBE(SpecialToken, MaybeSpecialToken) - - -static MaybeSpecialToken recognize_spec_token(char* line, size_t* pos) { - // TODO: add more error guards for peekaheads - char next_ch; - - switch (line[*pos]) { - case '|': - (*pos)++; - return (MaybeSpecialToken){ - .some = true, - .value = (SpecialToken){ - .kind = SPEC_OP, - .as.op = OP_PIPE, - } - }; - case '>': - next_ch = line[(*pos)+1]; - switch (next_ch) { - case '(': - return (MaybeSpecialToken){.some = false}; - case '>': - *pos += 2; - return (MaybeSpecialToken){ - .some = true, - .value = (SpecialToken){ - .kind = SPEC_OP, - .as.op = OP_REDIR_W_APPEND, - } - }; - default: - (*pos)++; - return (MaybeSpecialToken){ - .some = true, - .value = (SpecialToken){ - .kind = SPEC_OP, - .as.op = OP_REDIR_W_TRUNC, - } - }; - } - case '<': - next_ch = line[(*pos)+1]; - if (line[(*pos)+1] == '(') { - return (MaybeSpecialToken){.some = false}; - } else { - (*pos)++; - return (MaybeSpecialToken){ - .some = true, - .value = (SpecialToken){ - .kind = SPEC_OP, - .as.op = OP_REDIR_R, - } - }; - } - default: - return (MaybeSpecialToken){.some = false}; - } -} - -TokenVec* lex_level(char* line, size_t* pos, char until, TokenVecVec* tok_seq_pool) { - TokenVec tokens = make_TokenVec(256); - LexingBuffer buf = {.word_germ = make_Word(256), .lit_germ = make_String(256)}; - while (line[*pos] != until) { - if (line[*pos] == ' ') { - MaybeToken m_tok = consolidate_buffer(&buf); - if (m_tok.some) { - push_to_TokenVec(&tokens, m_tok.value); - } - while (line[*pos] == ' ') (*pos)++; - continue; - } - MaybeSpecialToken m_spec = recognize_spec_token(line, pos); - if (m_spec.some) { - MaybeToken m_tok = consolidate_buffer(&buf); - if (m_tok.some) { - push_to_TokenVec(&tokens, m_tok.value); - } - push_to_TokenVec(&tokens, (Token){.kind = TOK_SPEC, .as.spec = m_spec.value}); - continue; - } - - if (line[*pos] == '\'') { - Chunk chunk = collect_single_q_section(line, pos); - push_to_Word(&buf.word_germ, chunk); - } else if (line[*pos] == '\"') { - Chunk chunk = collect_double_q_section(line, pos); - push_to_Word(&buf.word_germ, chunk); - } else if (line[*pos] == '<' && line[(*pos)+1] == '(') { - *pos += 2; - MaybeToken m_tok = consolidate_buffer(&buf); - if (m_tok.some) { - push_to_TokenVec(&tokens, m_tok.value); - } - TokenVec* sub_toks = lex_level(line, pos, ')', tok_seq_pool); - (*pos)++; - push_to_TokenVec(&tokens, (Token){ - .kind = TOK_SPEC, - .as.spec = (SpecialToken){ - .kind = SPEC_SUB_IN, - .as.proc_sub_region = sub_toks - } - }); - } else if (line[*pos] == '>' && line[(*pos)+1] == '(') { - *pos += 2; - MaybeToken m_tok = consolidate_buffer(&buf); - if (m_tok.some) { - push_to_TokenVec(&tokens, m_tok.value); - } - TokenVec* sub_toks = lex_level(line, pos, ')', tok_seq_pool); - (*pos)++; - push_to_TokenVec(&tokens, (Token){ - .kind = TOK_SPEC, - .as.spec = (SpecialToken){ - .kind = SPEC_SUB_OUT, - .as.proc_sub_region = sub_toks - } - }); - } else { - push_to_String(&buf.lit_germ, line[(*pos)++]); - } - } - MaybeToken m_last = consolidate_buffer(&buf); - if (m_last.some) { - push_to_TokenVec(&tokens, m_last.value); - } - - if (until == '\0') { - push_to_TokenVec(&tokens, (Token){.kind = TOK_SPEC, .as.spec = (SpecialToken){.kind = SPEC_OP, .as.op = OP_EOL}}); - } - return push_to_TokenVecVec(tok_seq_pool, tokens); -} - -Ast lex(char* input) { - size_t line_pos = 0; - TokenVecVec token_seqs = make_TokenVecVec(256); - TokenVec* root_ptr = lex_level(input, &line_pos, '\0', &token_seqs); - return (Ast){.region_pool = token_seqs, .root = root_ptr}; -} diff --git a/redes/main.c b/redes/main.c deleted file mode 100644 index dc451f9..0000000 --- a/redes/main.c +++ /dev/null @@ -1,23 +0,0 @@ -#include <stdlib.h> -#include <stdio.h> -#include <readline/readline.h> -#include <readline/history.h> -#include <string.h> - -#include "syntax.h" -#include "stages.h" - - -int main() { - char* line; - while (1) { - line = readline("$ "); - if (line[0] == '\0') continue; - if (strcmp(line, "exit") == 0) exit(0); - add_history(line); - Ast ast = lex(line); - PipelineTree pltree = process_ast(ast); - execute_pipeline_tree(pltree); - } - free(line); -} diff --git a/redes/preproc.c b/redes/preproc.c deleted file mode 100644 index 63e618f..0000000 --- a/redes/preproc.c +++ /dev/null @@ -1,135 +0,0 @@ -#include <assert.h> -#include <stdio.h> -#include "syntax.h" - -void split_str_on_space(char* str, StrVec* result) { - String buf = make_String(256); - for (int pos = 0; str[pos] != '\0'; pos++) { - if (str[pos] == ' ') { - push_to_StrVec(result, inner(&buf)); - buf = make_String(256); - } else { - push_to_String(&buf, str[pos]); - } - } - - if (buf.count > 0) { - char* buf_str = inner(&buf); - push_to_StrVec(result, buf_str); - } -} - -StrVec process_word(Word word) { - StrVec result = make_StrVec(256); - for (int i = 0; i < word.count; i++) { - Chunk chunk = *get_from_Word(&word, i); - switch (chunk.qmode) { - case SINGLE_Q: - push_to_StrVec(&result, chunk.as.lit_str); - break; - case DOUBLE_Q: - // TODO - exit(67); - break; - case UN_Q: - // TODO: this only does literals, implement the rest - split_str_on_space(chunk.as.lit_str, &result); - break; - } - } - return result; -} - - -typedef struct { - TokenKind kind; - union { - char* word; - SpecialToken spec; - } as; -} ExpandedToken; - -DECLARE_VEC(ExpandedToken, ExpandedTokenVec) - -Pipeline* process_token_sequence(TokenVec tokens, PipelineVec* pl_pool) { - - ExpandedTokenVec exp_tokens = make_ExpandedTokenVec(256); - - for (int m = 0; m < tokens.count; m++) { - Token tok = *get_from_TokenVec(&tokens, m); - StrVec strs; - switch (tok.kind) { - case TOK_SPEC: - push_to_ExpandedTokenVec(&exp_tokens, (ExpandedToken){.kind = TOK_SPEC, .as.spec = tok.as.spec}); - break; - case TOK_WORD: - strs = process_word(tok.as.word); - for (int n = 0; n < strs.count; n++) { - push_to_ExpandedTokenVec(&exp_tokens, (ExpandedToken){.kind = TOK_WORD, .as.word = *get_from_StrVec(&strs, n)}); - } - } - } - - Pipeline pl = make_Pipeline(256); - size_t tok_pos = 0; - - PlCommand curr_cmd = {.args = make_ArgVec(256), .redirects = make_RedirectVec(256), .conn = CONN_EOL}; - - PlCommand* root_pl; - for (int i = 0; i < exp_tokens.count; i++) { - ExpandedToken curr_tok = *get_from_ExpandedTokenVec(&exp_tokens, i); - ExpandedToken next_tok; - Redirect rd; - switch (curr_tok.kind) { - case TOK_WORD: - push_to_ArgVec(&curr_cmd.args, (Arg){.kind = ARG_LIT, .as.lit_str = curr_tok.as.word}); - break; - case TOK_SPEC: - switch (curr_tok.as.spec.kind) { - case SPEC_OP: - switch (curr_tok.as.spec.as.op) { - case OP_PIPE: - curr_cmd.conn = CONN_PIPE; - push_to_Pipeline(&pl, curr_cmd); - curr_cmd = (PlCommand){.args = make_ArgVec(256), .redirects = make_RedirectVec(256), .conn = CONN_EOL}; - break; - case OP_EOL: - push_to_Pipeline(&pl, curr_cmd); - break; - case OP_REDIR_R: - next_tok = *get_from_ExpandedTokenVec(&exp_tokens, ++i); - assert(next_tok.kind == TOK_WORD); - rd = (Redirect){.kind = REDIR_READ, .as.filename = next_tok.as.word}; - push_to_RedirectVec(&curr_cmd.redirects, rd); - break; - case OP_REDIR_W_APPEND: - next_tok = *get_from_ExpandedTokenVec(&exp_tokens, ++i); - assert(next_tok.kind == TOK_WORD); - rd = (Redirect){.kind = REDIR_WRITE_APPEND, .as.filename = next_tok.as.word}; - push_to_RedirectVec(&curr_cmd.redirects, rd); - break; - 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}; - push_to_RedirectVec(&curr_cmd.redirects, rd); - break; - default: - exit(63); - } - break; - default: - exit(62); - } - } - } - return push_to_PipelineVec(pl_pool, pl); -} - - -PipelineTree process_ast(Ast ast) { - PipelineVec pls = make_PipelineVec(256); - TokenVec root_toks = *ast.root; - Pipeline* root_pl = process_token_sequence(root_toks, &pls); - return (PipelineTree){.pl_pool = pls, root_pl}; -} diff --git a/redes/stages.h b/redes/stages.h deleted file mode 100644 index 4faaf14..0000000 --- a/redes/stages.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include "syntax.h" - -Ast lex(char* input); -PipelineTree process_ast(Ast ast); -void execute_pipeline_tree(PipelineTree pltree); diff --git a/redes/syntax.h b/redes/syntax.h deleted file mode 100644 index 0cdb76c..0000000 --- a/redes/syntax.h +++ /dev/null @@ -1,194 +0,0 @@ -# pragma once - -#include "../src/utils.h" - - -// Stage 1 - -typedef enum { - PLUS, - MINUS, - MULT, -DIV, -} BinOp; - -typedef enum { - ARITHM_INT_LIT, - ARITHM_BINOP, -} ArithmNodeKind; - -typedef struct ArithmNode ArithmNode; -struct ArithmNode { - ArithmNodeKind kind; - union { - int lit_val; - IntVec open_fds; - struct { - BinOp op; - ArithmNode* left; - ArithmNode* right; - } binop; - } as; -}; -DECLARE_VEC(ArithmNode, ArithmNodeVec) - - -typedef struct { - ArithmNodeVec nodes; - ArithmNode* root; -} ArithmAst; - - -typedef enum { - UN_Q, - SINGLE_Q, - DOUBLE_Q, -} QuotationMode; - -typedef enum { - CHUNK_LIT, - CHUNK_VAR, - CHUNK_CMDSUB, - CHUNK_ARITHM, -} ChunkKind; - -typedef struct { - QuotationMode qmode; - ChunkKind kind; - union { - char* lit_str; - char* varname; - ArithmAst arithm_expr; - // TODO: CHUNK_CMDSUB - } as; -} Chunk; - -DECLARE_VEC(Chunk, Word) - - -typedef enum { - TOK_WORD, - TOK_SPEC, -} TokenKind; - -typedef enum { - OP_PIPE, - OP_REDIR_W_TRUNC, - OP_REDIR_W_APPEND, - OP_REDIR_R, - OP_EOL, -} OperatorToken; - - -typedef enum { - SPEC_OP, - SPEC_SUB_IN, - SPEC_SUB_OUT, -} SpecialTokenKind; - -typedef struct { - SpecialTokenKind kind; - union { - OperatorToken op; - void* proc_sub_region; - } as; -} SpecialToken; - - -typedef struct Token Token; -DECLARE_VEC(Token*, TokenPtrVec) - -struct Token { - TokenKind kind; - union { - Word word; - SpecialToken spec; - } as; -}; - -DECLARE_VEC(Token, TokenVec) -DECLARE_VEC(TokenVec, TokenVecVec) - -typedef struct { - TokenVecVec region_pool; - TokenVec* root; -} Ast; - - - -// Stage 2 - - -typedef enum { - REDIR_WRITE_TRUNC, - REDIR_WRITE_APPEND, - REDIR_READ, - REDIR_FDS, -} RedirectKind; - -typedef struct { - RedirectKind kind; - union { - char* filename; - struct{int from; int to;} fds; - } as; -} Redirect; - -DECLARE_VEC(Redirect, RedirectVec) - -typedef struct PlCommand PlCommand; - -typedef enum { - ARG_PS_IN, - ARG_PS_OUT, - ARG_LIT, -} ArgKind; - -typedef struct { - ArgKind kind; - union { - char* lit_str; - void* sub_pipeline; - } as; -} Arg; - -DECLARE_VEC(Arg, ArgVec) - - -typedef enum { - CONN_PIPE, - CONN_EOL, -} Connector; - - -struct PlCommand { - ArgVec args; - RedirectVec redirects; - Connector conn; -}; - -DECLARE_VEC(PlCommand, Pipeline) -DECLARE_VEC(Pipeline, PipelineVec) - -typedef struct { - PipelineVec pl_pool; - Pipeline* root; -} PipelineTree; - - - -// Stage 3 - -typedef struct { - int redirected; - int to; -} FdRedirect; - -DECLARE_VEC(FdRedirect, FdRedirectVec) - -typedef struct { - char** args; - FdRedirectVec redirects; - int stdin_fd, stdout_fd; - IntVec open_fds; -} ExecutableCommand; |
