Commits

Steven! Ragnarök committed 4b60576

Interpreter sets exit status variables.

  • Participants
  • Parent commits 6c37256

Comments (0)

Files changed (5)

include/interpreter.h

 #ifndef SH142TYPES
 #include "sh142types.h"
 #endif
+
+#include "fifo.h"
 /* The interpreter for the sh142 command shell. Works on a tree of ASTNodes */
 
 void interpret(ast_node *root);
-void interpret_command(ast_node *command);
-void interpret_var_assign(ast_node *var_assign);
+int interpret_command(ast_node *command);
+int interpret_var_assign(ast_node *var_assign);
 char *interpret_variable(ast_node *variable);
 char *interpret_value(ast_node *value);
 
+/* Variables for the Exit Status FIFO. */
+#define UNSET_STATUS -99
+int *exitstatus_head;
+int exitstatuses[MAX_SAVED_EXITSTATUSES];
+void set_exitstatuses(void);

include/sh142types.h

 /* The maximum size of a single token. */
 #define MAX_TOKEN_LENGTH 64
 #define MAX_STRING_LENGTH 256
+#define MAX_SAVED_EXITSTATUSES 10
 
 /* Different types of tokens!!!! */
 typedef enum { COMMAND, VARASSIGN, VALUE, VARIABLE } node_type;
 int fifo_peek(int fifoc, int fifo[], int *fifohead, int level) {
-	if ((level -= *fifohead) < 0) {
-		level += fifoc;
+	int i = *fifohead - level;
+	if (i < 0) {
+		i += fifoc;
 	}
-	return fifo[level];
+	return fifo[i];
 }
 
 int fifo_push(int fifoc, int fifo[], int *fifohead, int newitem) {
-	if (++*fifohead > fifoc) {
-		fifohead -= fifoc;
+	if (++*fifohead >= fifoc) {
+		*fifohead -= fifoc;
 	}
 	return fifo[*fifohead] = newitem;
 }

src/interpreter.c

 #include <stdlib.h>
+#include <stdio.h>
 #include <string.h>
 #include <unistd.h>
 #include <sys/wait.h>
 #define OVERWRITE 1
 
 void interpret(ast_node *root) {
+	int exit_status;
 	if (root->type == COMMAND) {
-		interpret_command(root);
-		return;
+		exit_status = interpret_command(root);
 	} else if (root->type == VARASSIGN) {
-		interpret_var_assign(root);
+		exit_status = interpret_var_assign(root);
 	}
+
+	fifo_push(MAX_SAVED_EXITSTATUSES, exitstatuses, exitstatus_head, exit_status);
+	set_exitstatuses();
 	/* Free AST */
 	/* Free tokens */
 	return;
 }
 
-void interpret_command(ast_node* command) {
+int interpret_command(ast_node* command) {
 	int cmdstats, argc = 0;
 	pid_t cmdpid;
 	char *argv[MAX_TOKEN_LENGTH];
 	} else {
 		waitpid(cmdpid, &cmdstats, 0);
 	}
-	return;
+	return WEXITSTATUS(cmdstats);
 }
 
-void interpret_var_assign(ast_node *var_assign) {
+int interpret_var_assign(ast_node *var_assign) {
 	char *varname, *value;
 	varname = var_assign->children->node->token;
 	value = var_assign->children->next->node->token;
-	setenv(varname, value, OVERWRITE);
+	return setenv(varname, value, OVERWRITE);
 }
 
 char *interpret_variable(ast_node *variable) {
 	return value->token;
 }
 
+void set_exitstatuses() {
+	int i, status;
+	char var[2]; /* Only need 3 characters. Since statuses range from 0-255. */
+	char val[3]; /* Only need 3 characters. Since statuses range from 0-255. */
+	for (i = 0; i < MAX_SAVED_EXITSTATUSES; i++) {
+		sprintf(var, "?%1d", i);
+		status = fifo_peek(MAX_SAVED_EXITSTATUSES, exitstatuses,
+				exitstatus_head, i);
+		if (status != UNSET_STATUS) {
+			sprintf(val, "%3d", status);
+			setenv(var, val, OVERWRITE);
+		} else {
+			unsetenv(var);
+		}
+	}
+	return;
+}
+
 
 int main() {
 	char *input;
+	int i;
+
+	/* Set up exit status FIFO. */
+
+	exitstatus_head = malloc(sizeof(int));
+	*exitstatus_head = 0;
+	for (i = 0; i < MAX_SAVED_EXITSTATUSES; i++) {
+		exitstatuses[i] = UNSET_STATUS;
+	}
 	while(1) {
 		input = readline(PROMPT_STRING);
 		/* Break out when the user exits. */