ESH

Executive Shell
git clone http://git.omkov.net/ESH
Log | Tree | Refs | README | Download

AuthorJamozed <[email protected]>
Date2021-11-18 13:02:33
Commit2dbb34a3c85acb630016eb6735147ecf23879630
Parent14bad1bb658817185a69b92f06be5db52b7b83ae

Implement single quote parsing

Diffstat

M CHANGELOG | 3 ++-
M src/bltns/eval.c | 2 +-
M src/exec.c | 3 ++-
M src/lex.c | 19 ++++++++++++++++---
M src/main.c | 2 ++
M src/parse.c | 6 ++++--
M src/util/stack.c | 13 +++++++------
M src/util/stack.h | 7 +++++--

8 files changed, 39 insertions, 16 deletions

diff --git a/CHANGELOG b/CHANGELOG
index 1fc0871..d108160 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,7 @@
 0.5.1,
 * Implement pipe handling
 * Implement redirect handling
+* Implement single quote parsing
 * Remove repeated warning when eshrc is absent
 * Fix unintended fallthrough when handling extended escape sequences
 
@@ -36,7 +37,7 @@
 * Add PWD builtin
 * Move to token based parsing
 * Add rudimentary support for multi-line commands
-* Rebrand to ESH, OMKOV Shell
+* Rebrand to OSH, OMKOV Shell
 
 0.1.0, 2020-01-31
 * Implement basic shell loop
diff --git a/src/bltns/eval.c b/src/bltns/eval.c
index 797cf3b..6c70612 100644
--- a/src/bltns/eval.c
+++ b/src/bltns/eval.c
@@ -64,7 +64,7 @@ int bltn_eval(int ac, char *av[]) {
 	args = assert_calloc(size, sizeof (*args)); dest = args;
 
 	for (UINT i = 0; i != ac - opt.ind; i += 1) {
-		if (i != 0) { strncat((char *)dest, " ", 1); dest += 1; }
+		if (i != 0) { strncat(dest, " ", 1); dest += 1; }
 		strcat((char *)dest, av[opt.ind + i]); dest += strlen(av[opt.ind + i]);
 	}
 
diff --git a/src/exec.c b/src/exec.c
index 1dbb7b5..d3e882f 100644
--- a/src/exec.c
+++ b/src/exec.c
@@ -58,7 +58,8 @@ int execute(ast a, int fdi, int fd[2]) {
 
 /* Execute a command statement. */
 static int execute_comm(ast a, int fdi, int fd[2]) {
-	if (!a->s) { printf("WDTA?\n"); return _ret; } /* What does this achieve? */
+	/* If the command is null, then do nothing */
+	if (!a->s) { return _ret; }
 
 	for (struct bltn *b = bltns; b->s; b += 1) {
 		if (strcmp((char *)a->s, b->s) == 0) {
diff --git a/src/lex.c b/src/lex.c
index 426f62d..e05d4e1 100644
--- a/src/lex.c
+++ b/src/lex.c
@@ -31,8 +31,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
 */
 
 #include "lex.h"
+#include "util/stack.h"
 #include "util/util.h"
 
+#include "cll/error.h"
+
 #include <ctype.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -81,13 +84,23 @@ skip:;
 
 	/* Handle anything else as a word */
 	default: {
-		char *s = P; UINT sl;
+		stack s = stack_init(sizeof (char), NULL);
 
-		for (P += 1; P != Q && C != '\n' && C != ';' && C != ' '; P += 1) {
+		for (; P != Q && C != '\n' && C != ';' && C != ' '; P += 1) {
 			if (C == '|' || C == '<' || C == '>') { break; }
+			
+			/* Handle single quotes */
+			else if (C == '\'') for (P += 1;; P += 1) {
+				if (P == Q) { warn("Missing closing \'"); break; }
+				else if (C == '\'') { break; }
+				else { STACK_PUSH(&s, C); }
+			}
+			
+			/* Handle all other characters */
+			else { STACK_PUSH(&s, C); }
 		}
 
-		sl = P - s; T.s = strndup(s, sl); T.k = TK_WORD;
+		T.s = strndup(s.a, s.al); T.k = TK_WORD; stack_free(&s);
 	} break;
 	}
 
diff --git a/src/main.c b/src/main.c
index 4c00b0d..a081388 100644
--- a/src/main.c
+++ b/src/main.c
@@ -36,6 +36,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
 		entries.
 	TODO investigate builtins and their functionality with regards to pipes.
 	TODO reimplement compound commands without a dedicated AST kind.
+	FIXME without compound commands of some kind, files cannot be executed, as
+		they are read in as a single string.
 */
 
 #include "conf.h"
diff --git a/src/parse.c b/src/parse.c
index 898e644..5ea114a 100644
--- a/src/parse.c
+++ b/src/parse.c
@@ -58,7 +58,9 @@ static ast parse_rerr(lex *l);
 ast ast_init(void) { return assert_calloc(1, sizeof (struct ast_s)); }
 
 /* Uninitialise an AST node and its children. */
-void ast_free(ast a) { if (a) { ast_free(a->lc); ast_free(a->rc); free(a); }; }
+void ast_free(ast a) {
+	if (a) { ast_free(a->lc); ast_free(a->rc); stack_free(&a->c); free(a); };
+}
 
 /* Parse a program. */
 ast parse(lex *l) {
@@ -79,7 +81,7 @@ ast parse(lex *l) {
 /* Parse a command statement. */
 static ast parse_comm(lex *l) {
 	ast a = ast_init(); a->k = AK_COMM;
-	a->c = stack_init(&free);
+	a->c = stack_init(sizeof (char *), &free);
 
 	/* Push each command argument onto the child stack */
 	stack_push(&a->c, (a->s = lex_next(l).s));
diff --git a/src/util/stack.c b/src/util/stack.c
index c095440..5a66f24 100644
--- a/src/util/stack.c
+++ b/src/util/stack.c
@@ -34,17 +34,18 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
 #include "util.h"
 
 #include <stdlib.h>
+#include <string.h>
 
 /* Initialise a stack. */
-extern stack stack_init(void (*free)(void *)) {
-	return (stack){ NULL, 0, 0, free };
+extern stack stack_init(UINT el, void (*free)(void *)) {
+	return (stack){ NULL, 0, 0, el, free };
 }
 
 /* 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]);
+			void *e; memcpy(&e, s->a + i * s->el, s->el); s->free(e);
 		}
 
 		free(s->a);
@@ -53,11 +54,11 @@ extern void stack_free(stack *s) {
 
 /* 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;
+	s->a = assert_realloc(s->a, (s->ac += 1) * s->el);
+	memcpy(s->a + (s->al * s->el), &e, s->el); 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];
+	void *e; memcpy(&e, s->a + ((s->al -= 1) * s->el), s->el); return e;
 }
diff --git a/src/util/stack.h b/src/util/stack.h
index dcdd135..aa7da85 100644
--- a/src/util/stack.h
+++ b/src/util/stack.h
@@ -35,12 +35,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
 
 #include "util.h"
 
-typedef struct { void *a; UINT al, ac; void (*free)(void *); } stack;
+#define STACK_PUSH(s, e) stack_push(s, (void *)(UINT)(e));
 
-extern stack stack_init(void (*free)(void *));
+typedef struct { void *a; UINT al, ac, el; void (*free)(void *); } stack;
+
+extern stack stack_init(UINT el, void (*free)(void *));
 extern void  stack_free(stack *s);
 
 extern void  stack_push(stack *s, void *e);
 extern void *stack_pop(stack *s);
 
+
 #endif // ESH_UTIL_STACK_H_5W2ABS0S