Author | Jamozed <[email protected]> |
Date | 2021-11-12 12:33:35 |
Commit | be40c3ece09a28e9a5a7ce4d4f5bf674bdcd1217 |
Parent | 1c707b2204375e3ef880317170ec9ba3a46ee9d9 |
Refactor the array implementation into a stack
Diffstat
M | src/esh.h | | | 1 | - |
M | src/exec.c | | | 8 | ++++---- |
M | src/main.c | | | 2 | +- |
M | src/parse.c | | | 66 | +++++++++++++++++++++++++++++++++++++++++++++++------------------- |
M | src/parse.h | | | 9 | +++++---- |
R | src/util/array.c -> src/util/stack.c | | | 39 | +++++++++++++++++++++------------------ |
R | src/util/array.h -> src/util/stack.h | | | 21 | ++++++++++----------- |
D | src/util/llist.c | | | 73 | ------------------------------------------------------------------------- |
D | src/util/llist.h | | | 51 | --------------------------------------------------- |
M | src/util/util.c | | | 12 | ++++++------ |
M | src/util/util.h | | | 8 | +++----- |
11 files changed, 97 insertions, 193 deletions
diff --git a/src/esh.h b/src/esh.h index 528deca..c6d9db9 100644 --- a/src/esh.h +++ b/src/esh.h @@ -34,7 +34,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. #define ESH_ESH_H_SAZDXXFN #include "parse.h" -#include "util/array.h" #include "util/util.h" extern bool Lflag, Pflag; diff --git a/src/exec.c b/src/exec.c index 1b58935..9b41634 100644 --- a/src/exec.c +++ b/src/exec.c @@ -62,8 +62,8 @@ int execute(ast a) { static int execute_comp(ast a) { register int ret = 0; - for (UINT i = 0; i != a->c->size; i += 1) { - ret = execute(a->c->data[i]); + for (UINT i = 0; i != a->c.al; i += 1) { + ret = execute(((ast *)a->c.a)[i]); } return ret; @@ -75,11 +75,11 @@ static int execute_comm(ast a) { for (struct bltn *b = bltns; b->s; b += 1) { if (strcmp((char *)a->s, b->s) == 0) { - return b->f(a->c->size - 1, (char **)a->c->data); + return b->f(a->c.al - 1, a->c.a); } } - return WEXITSTATUS(launch((u8 **)a->c->data)); + return WEXITSTATUS(launch(a->c.a)); } /* Fork and execute an executable. */ diff --git a/src/main.c b/src/main.c index a59beed..34bdcac 100644 --- a/src/main.c +++ b/src/main.c @@ -81,7 +81,7 @@ int main(int ac, char *av[]) { (void)(ac); A0 = av[0]; signal(SIGINT, &reset); signal(SIGTSTP, SIG_IGN); signal(SIGQUIT, SIG_IGN); if (errno) { warn("%s", serr()); } - if (!Lflag) { confread(); } + if (!Lflag && !Pflag) { confread(); } do { if (sigsetjmp(jmp, 1)) { fputc('\n', stdout); } jmpflag = true; diff --git a/src/parse.c b/src/parse.c index c818e0a..dea7238 100644 --- a/src/parse.c +++ b/src/parse.c @@ -30,8 +30,12 @@ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. */ +/* + TODO: Continue implenting pipes and redirects. +*/ + #include "esh.h" -#include "util/llist.h" +#include "util/stack.h" #include "util/util.h" #include "cll/error.h" @@ -39,20 +43,23 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. #include <stdio.h> #include <stdlib.h> -char *ast_ks[] = { "NULL", "COMP", "COMM" }; +char *ast_ks[] = { + "NULL", "COMP", "COMM", + "PIPE", "RDIN", "ROUT", "RERR" +}; static ast parse_comp(lex *l); static ast parse_comm(lex *l); +static ast parse_pipe(lex *l); +static ast parse_rdin(lex *l); +static ast parse_rout(lex *l); +static ast parse_rerr(lex *l); /* Initialise an AST node. */ -ast ast_init(void) { - return assert_calloc(1, sizeof (struct ast_)); -} +ast ast_init(void) { return assert_calloc(1, sizeof (struct ast_s)); } -/* Uninitialise an AST node. */ -void ast_free(ast a) { - if (a) { array_free(a->c); free(a); } -} +/* Uninitialise an AST node and its children. */ +void ast_free(ast a) { if (a) { ast_free(a->lc); ast_free(a->rc); free(a); }; } /* Parse a program. */ ast parse(lex *l) { @@ -64,10 +71,10 @@ ast parse(lex *l) { /* Parse a comound statement. */ static ast parse_comp(lex *l) { ast a = ast_init(); a->k = AK_COMP; - a->c = array_init((void (*)(ptr))&ast_free); + a->c = stack_init((void (*)(void *))&ast_free); /* Push each command onto the array */ - for (; lex_peek(l).k != TK_EOF;) { array_push(a->c, parse_comm(l)); } + for (; lex_peek(l).k != TK_EOF;) { stack_push(&a->c, parse_comm(l)); } return a; } @@ -75,15 +82,36 @@ static ast parse_comp(lex *l) { /* Parse a command statement. */ static ast parse_comm(lex *l) { ast a = ast_init(); a->k = AK_COMM; - a->c = array_init(NULL); + a->c = stack_init(&free); /* Push each command argument onto the array. */ - array_push(a->c, (a->s = lex_next(l).s)); - for (tok t; (t = lex_next(l)).k == TK_WORD;) { array_push(a->c, t.s); } + stack_push(&a->c, (a->s = lex_next(l).s)); + for (tok t; (t = lex_next(l)).k == TK_WORD;) { stack_push(&a->c, t.s); } + + stack_push(&a->c, NULL); return a; +} + +/* Parse a pipe statement. */ +static ast parse_pipe(lex *l) { + +} + +/* Parse a redirect stdin statement. */ +static ast parse_rdin(lex *l) { + +} + +/* Parse a redirect stdout statement. */ +static ast parse_rout(lex *l) { - array_push(a->c, NULL); return a; } +/* Parse a redirect stderr statement. */ +static ast parse_rerr(lex *l) { + +} + + /* Print parser debug output with an indent. */ static void ast_debug_indent(ast a, UINT i) { for (UINT j = 0; j != i; ++j) { printf("\t"); } @@ -93,14 +121,14 @@ static void ast_debug_indent(ast a, UINT i) { switch (a->k) { case AK_COMP: { printf("\n"); - for (UINT j = 0; j != a->c->size; j += 1) { - ast_debug_indent(a->c->data[j], i + 1); + for (UINT j = 0; j != a->c.al; j += 1) { + ast_debug_indent(((ast *)a->c.a)[j], i + 1); printf("\n"); } } break; case AK_COMM: { - for (UINT j = 0; j != a->c->size - 1; j += 1) { - printf(" %s", (u8 *)a->c->data[j]); + for (UINT j = 0; j != a->c.al - 1; j += 1) { + printf(" %s", ((char **)a->c.a)[j]); } } break; default: { warn("%s: Unimplemented AST (debug)", ast_ks[a->k]); } break; diff --git a/src/parse.h b/src/parse.h index 3339f5f..583db1b 100644 --- a/src/parse.h +++ b/src/parse.h @@ -34,16 +34,17 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. #define ESH_PARSE_H_R9WJSU27 #include "lex.h" -#include "util/array.h" +#include "util/stack.h" #include "util/util.h" typedef enum { - AK_NULL, AK_COMP, AK_COMM + AK_NULL, AK_COMP, AK_COMM, + AK_PIPE, AK_RDIN, AK_ROUT, AK_RERR, } ast_k; -typedef struct ast_ *ast; +typedef struct ast_s *ast; -struct ast_ { ast_k k; char *s; array c; }; +struct ast_s { ast_k k; char *s; ast lc, rc; stack c; }; extern char *ast_ks[]; diff --git a/src/util/llist.c b/src/util/llist.c deleted file mode 100644 index 9b49735..0000000 --- a/src/util/llist.c +++ /dev/null @@ -1,73 +0,0 @@ -// util/llist.c -// Linked list utility source file for ESH -// Copyright (C) 2021, Jakob Wakeling -// All rights reserved. - -/* -OMKOV Permissive Licence, version 1.0 - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal with -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimers. -* Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimers in the documentation and/or - other materials provided with the distribution. -* Neither the names of the copyright holders, nor the names of its contributors - may be used to endorse or promote products derived from this Software without - specific prior written permission. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT -HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. -*/ - -#include "llist.h" -#include "util.h" - -#include <stdlib.h> - -/* Initialise a linked list node. */ -static lnode lnode_init(void) { - return assert_calloc(1, sizeof (struct lnode_)); -} - -/* Uninitialise a linked list node. */ -static void lnode_free(lnode node) { - if (node) { lnode_free(node->next); free(node); } -} - -/* Initialise a linked list. */ -llist llist_init() { - return assert_calloc(1, sizeof (struct llist_)); -} - -/* Uninitialise a linked list. */ -void llist_free(llist list) { - if (list) { lnode_free(list->head); free(list); } -} - -/* Push a pointer to a linked list. */ -void llist_push(llist list, ptr data) { - lnode node = lnode_init(); node->data = data; - node->next = list->head; list->size += 1; list->head = node; -} - -/* Pop a pointer from a linked list. */ -ptr llist_pop(llist list) { - lnode node = list->head; ptr data = node->data; - list->head = node->next; list->size -= 1; lnode_free(node); return data; -} - -/* Peek at a pointer on a linked list without popping. */ -ptr llist_peek(llist list) { - return list->head->data; -} diff --git a/src/util/llist.h b/src/util/llist.h deleted file mode 100644 index 7f5a9b4..0000000 --- a/src/util/llist.h +++ /dev/null @@ -1,51 +0,0 @@ -// util/llist.h -// Linked list utility header file for ESH -// Copyright (C) 2021, Jakob Wakeling -// All rights reserved. - -/* -OMKOV Permissive Licence, version 1.0 - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal with -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimers. -* Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimers in the documentation and/or - other materials provided with the distribution. -* Neither the names of the copyright holders, nor the names of its contributors - may be used to endorse or promote products derived from this Software without - specific prior written permission. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT -HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. -*/ - -#ifndef ESH_UTIL_LLIST_H_87ACJX8V -#define ESH_UTIL_LLIST_H_87ACJX8V - -#include "util.h" - -typedef struct lnode_ *lnode; -typedef struct llist_ *llist; - -struct lnode_ { lnode next; ptr data; }; -struct llist_ { lnode head; UINT size; }; - -extern llist llist_init(void); -extern void llist_free(llist list); - -extern void llist_push(llist list, ptr data); -extern ptr llist_pop(llist list); -extern ptr llist_peek(llist list); - -#endif // ESH_UTIL_LLIST_H_87ACJX8V diff --git a/src/util/array.c b/src/util/stack.c similarity index 70% rename from src/util/array.c rename to src/util/stack.c index 45f0a8d..c095440 100644 --- a/src/util/array.c +++ b/src/util/stack.c @@ -1,5 +1,5 @@ -// util/array.c -// Array utility source file for ESH +// util/stack.c +// Stack utility source file for ESH // Copyright (C) 2021, Jakob Wakeling // All rights reserved. @@ -30,31 +30,34 @@ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. */ -#include "array.h" +#include "stack.h" #include "util.h" #include <stdlib.h> -/* Initialise an array. */ -array array_init(void (*free)(ptr)) { - register array a = assert_calloc(1, sizeof (*a)); - a->free = free; return a; +/* Initialise a stack. */ +extern stack stack_init(void (*free)(void *)) { + return (stack){ NULL, 0, 0, free }; } -/* Uninitialise an array. */ -void array_free(array a) { - if (a) { - for (UINT i = 0; i != a->size; i += 1) { - if (a->free) { a->free(a->data[i]); } - else { free(a->data[i]); } +/* Uninitialise a stack. */ +extern void stack_free(stack *s) { + if (s) { + if (s->free) for (UINT i = 0; i != s->al; i += 1) { + s->free(((void **)s->a)[i]); } - free(a->data); free(a); + free(s->a); } } -/* Push a pointer to an array. */ -void array_push(array a, ptr data) { - a->data = assert_realloc(a->data, (a->size += 1) * sizeof (*a->data)); - a->data[a->size - 1] = data; +/* Push a pointer to the top of a stack. */ +extern void stack_push(stack *s, void *e) { + s->a = assert_realloc(s->a, (s->ac += 1) * sizeof (*s->a)); + ((void **)s->a)[s->al] = e; s->al += 1; +} + +/* Pop a pointer from the top of a stack. */ +extern void *stack_pop(stack *s) { + s->al -= 1; return ((void **)s->a)[s->al]; } diff --git a/src/util/array.h b/src/util/stack.h similarity index 80% rename from src/util/array.h rename to src/util/stack.h index 736bd53..dcdd135 100644 --- a/src/util/array.h +++ b/src/util/stack.h @@ -1,5 +1,5 @@ -// util/array.h -// Array utility header file for ESH +// util/stack.h +// Stack utility header file for ESH // Copyright (C) 2021, Jakob Wakeling // All rights reserved. @@ -30,18 +30,17 @@ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. */ -#ifndef ESH_UTIL_ARRAY_H_9LJ2QOUZ -#define ESH_UTIL_ARRAY_H_9LJ2QOUZ +#ifndef ESH_UTIL_STACK_H_5W2ABS0S +#define ESH_UTIL_STACK_H_5W2ABS0S #include "util.h" -typedef struct array_ *array; +typedef struct { void *a; UINT al, ac; void (*free)(void *); } stack; -struct array_ { ptr *data; UINT size; void (*free)(ptr); }; +extern stack stack_init(void (*free)(void *)); +extern void stack_free(stack *s); -extern array array_init(void (*free)(ptr)); -extern void array_free(array a); +extern void stack_push(stack *s, void *e); +extern void *stack_pop(stack *s); -extern void array_push(array a, ptr data); - -#endif // ESH_UTIL_ARRAY_H_9LJ2QOUZ +#endif // ESH_UTIL_STACK_H_5W2ABS0S diff --git a/src/util/util.c b/src/util/util.c index a8b7572..c38d2bd 100644 --- a/src/util/util.c +++ b/src/util/util.c @@ -36,19 +36,19 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. #include <stdlib.h> /* Allocate and assert memory. */ -ptr assert_malloc(UINT l) { - register ptr r = malloc(l); +void *assert_malloc(UINT l) { + register void *r = malloc(l); assert(r); return r; } /* Allocate and assert memory. */ -ptr assert_calloc(UINT n, UINT l) { - register ptr r = calloc(n, l); +void *assert_calloc(UINT n, UINT l) { + register void *r = calloc(n, l); assert(r); return r; } /* Reallocate and assert memory. */ -ptr assert_realloc(ptr p, UINT l) { - register ptr r = realloc(p, l); +void *assert_realloc(void *p, UINT l) { + register void *r = realloc(p, l); assert(r); return r; } diff --git a/src/util/util.h b/src/util/util.h index 3e9c772..18d3015 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -36,8 +36,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. #include <stdbool.h> #include <stdint.h> -typedef void *ptr; - typedef uint8_t u8; typedef uint16_t u16; typedef uint32_t u32; @@ -54,8 +52,8 @@ typedef float f32; typedef double f64; typedef long double f128; -extern ptr assert_malloc(UINT l); -extern ptr assert_calloc(UINT n, UINT l); -extern ptr assert_realloc(ptr p, UINT l); +extern void *assert_malloc(UINT l); +extern void *assert_calloc(UINT n, UINT l); +extern void *assert_realloc(void * p, UINT l); #endif // ESH_UTIL_UTIL_H_KP8NS9DC