summaryrefslogtreecommitdiff
path: root/zwgc/exec.c
diff options
context:
space:
mode:
authorGravatar Marc Horowitz <marc@mit.edu>1989-11-01 20:02:01 +0000
committerGravatar Marc Horowitz <marc@mit.edu>1989-11-01 20:02:01 +0000
commitd13d8a046838ce3d0e2643bb5b49f2ff77d679ca (patch)
tree05737bc11e3461836ce817939b9129ed58545ac7 /zwgc/exec.c
parentfd994e4099ad66fb3bf26cd636ca5d5cae72da68 (diff)
Initial revision
Diffstat (limited to 'zwgc/exec.c')
-rw-r--r--zwgc/exec.c444
1 files changed, 444 insertions, 0 deletions
diff --git a/zwgc/exec.c b/zwgc/exec.c
new file mode 100644
index 0000000..e7ff111
--- /dev/null
+++ b/zwgc/exec.c
@@ -0,0 +1,444 @@
+/****************************************************************************/
+/* */
+/* Module containing code to execute a program: */
+/* */
+/****************************************************************************/
+
+#include <zephyr/zephyr.h>
+#include "new_memory.h"
+#include "exec.h"
+#include "eval.h"
+#include "node.h"
+#include "buffer.h"
+#include "port.h"
+#include "variables.h"
+#include "notice.h"
+
+/****************************************************************************/
+/* */
+/* Utility subroutines: */
+/* */
+/****************************************************************************/
+
+static string eval_exprlist_to_string(exprlist)
+ Node *exprlist;
+{
+ string result = string_Copy("");
+ string temp;
+ int first_time = 1;
+
+ for (; exprlist; exprlist=exprlist->next) {
+ if (!first_time)
+ result = string_Concat2(result, " ");
+ else
+ first_time = 0;
+
+ temp = eval_expr(exprlist);
+ result = string_Concat2(result, temp);
+ free(temp);
+ }
+
+ return(result);
+}
+
+static char **eval_exprlist_to_args(exprlist)
+ Node *exprlist;
+{
+ char **result = (char **)malloc(sizeof(char *));
+ int argc = 0;
+
+ for (; exprlist; exprlist=exprlist->next) {
+ result[argc] = eval_expr(exprlist);
+ argc++;
+ result = (char **)realloc(result, (argc+1)*sizeof(char *));
+ }
+
+ result[argc] = NULL;
+ return(result);
+}
+
+static void free_args(args)
+ char **args;
+{
+ char **p;
+
+ for (p=args; *p; p++) {
+ free(*p);
+ }
+
+ free(args);
+}
+
+/****************************************************************************/
+/* */
+/* Subroutines to handle each particular statement type: */
+/* */
+/****************************************************************************/
+
+#define NOBREAK 0
+#define BREAK 1
+#define EXIT 2
+
+/*ARGSUSED*/
+static int exec_noop(node)
+ Node *node;
+{
+ return(NOBREAK);
+}
+
+/*ARGSUSED*/
+static int exec_break(node)
+ Node *node;
+{
+ return(BREAK);
+}
+
+/*ARGSUSED*/
+static int exec_exit(node)
+ Node *node;
+{
+ return(EXIT);
+}
+
+static int exec_set(node)
+ Node *node;
+{
+ var_set_variable_then_free_value(node->d.nodes.first->d.string_constant,
+ eval_expr(node->d.nodes.second));
+
+ return(NOBREAK);
+}
+
+static int exec_execport(node)
+ Node *node;
+{
+ string name = eval_expr(node->d.nodes.first);
+ char **argv = eval_exprlist_to_args(node->d.nodes.second);
+
+ create_subprocess_port(name, argv);
+
+ free(name);
+ free_args(argv);
+ return(NOBREAK);
+}
+
+static int exec_appendport(node)
+ Node *node;
+{
+ string name, filename;
+
+ name = eval_expr(node->d.nodes.first);
+ filename = eval_expr(node->d.nodes.second);
+
+ create_file_append_port(name, filename);
+
+ free(name);
+ free(filename);
+ return(NOBREAK);
+}
+
+static int exec_inputport(node)
+ Node *node;
+{
+ string name, filename;
+
+ name = eval_expr(node->d.nodes.first);
+ filename = eval_expr(node->d.nodes.second);
+
+ create_file_input_port(name, filename);
+
+ free(name);
+ free(filename);
+ return(NOBREAK);
+}
+
+static int exec_outputport(node)
+ Node *node;
+{
+ string name, filename;
+
+ name = eval_expr(node->d.nodes.first);
+ filename = eval_expr(node->d.nodes.second);
+
+ create_file_output_port(name, filename);
+
+ free(name);
+ free(filename);
+ return(NOBREAK);
+}
+
+static int exec_closeinput(node)
+ Node *node;
+{
+ string name;
+
+ name = eval_expr(node->d.nodes.first);
+ close_port_input(name);
+
+ free(name);
+ return(NOBREAK);
+}
+
+static int exec_closeoutput(node)
+ Node *node;
+{
+ string name;
+
+ name = eval_expr(node->d.nodes.first);
+ close_port_output(name);
+
+ free(name);
+ return(NOBREAK);
+}
+
+static int exec_closeport(node)
+ Node *node;
+{
+ string name;
+
+ name = eval_expr(node->d.nodes.first);
+ close_port_input(name);
+ close_port_output(name);
+
+ free(name);
+ return(NOBREAK);
+}
+
+static int exec_put(node)
+ Node *node;
+{
+ string name, temp;
+
+ if (node->d.nodes.second)
+ temp = eval_exprlist_to_string(node->d.nodes.second);
+ else
+ temp = string_Copy(buffer_to_string());
+
+ if (node->d.nodes.first) {
+ name = eval_expr(node->d.nodes.first);
+
+ write_on_port(name, temp, strlen(temp));
+ free(name);
+ } else
+ write_on_port(var_get_variable("output_driver"), temp, strlen(temp));
+
+ free(temp);
+ return(NOBREAK);
+}
+
+static int exec_print(node)
+ Node *node;
+{
+ string temp;
+
+ temp = eval_exprlist_to_string(node->d.nodes.first);
+ append_buffer(temp);
+ free(temp);
+
+ return(NOBREAK);
+}
+
+/*ARGSUSED*/
+static int exec_clearbuf(node)
+ Node *node;
+{
+ clear_buffer();
+
+ return(NOBREAK);
+}
+
+static int exec_case(node)
+ Node *node;
+{
+ string constant,temp;
+ Node *match, *cond;
+ int equal_p;
+
+ constant = string_Downcase(eval_expr(node->d.nodes.first));
+
+ for (match=node->d.nodes.second; match; match=match->next) {
+ cond = match->d.nodes.first;
+ if (!cond) { /* default case */
+ free(constant);
+ return(exec_subtree(match->d.nodes.second));
+ }
+ for (; cond; cond=cond->next) {
+ temp = string_Downcase(eval_expr(cond));
+ equal_p = string_Eq(constant, temp);
+ free(temp);
+ if (equal_p) {
+ free(constant);
+ return(exec_subtree(match->d.nodes.second));
+ }
+ }
+ }
+
+ free(constant);
+ return(NOBREAK);
+}
+
+static int exec_while(node)
+ Node *node;
+{
+ int continue_code = NOBREAK;
+
+ while (eval_bool_expr(node->d.nodes.first)) {
+ continue_code = exec_subtree(node->d.nodes.second);
+ if (continue_code != NOBREAK)
+ break;
+ }
+
+ if (continue_code == BREAK)
+ continue_code = NOBREAK;
+
+ return(continue_code);
+}
+
+static int exec_if(node)
+ Node *node;
+{
+ Node *conds;
+
+ for (conds=node->d.nodes.first; conds; conds=conds->next)
+ if (eval_bool_expr(conds->d.nodes.first))
+ return(exec_subtree(conds->d.nodes.second));
+
+ return(NOBREAK);
+}
+
+static int exec_exec(node)
+ Node *node;
+{
+ int pid;
+ char **argv = eval_exprlist_to_args(node->d.nodes.first);
+
+ pid = fork();
+ if (pid == -1) {
+ fprintf(stderr, "zwgc: error while attempting to fork: ");
+ perror("");
+ } else if (pid == 0) { /* in child */
+ execvp(argv[0], argv);
+ fprintf(stderr,"zwgc: unable to exec %s: ", argv[0]);
+ perror("");
+ _exit(errno);
+ }
+
+ free_args(argv);
+ return(NOBREAK);
+}
+
+/* <<<>>> */
+extern int exec_fields();
+
+static struct _Opstuff {
+ int (*exec)();
+} opstuff[] = {
+ { exec_noop }, /* string_constant */
+ { exec_noop }, /* varref */
+ { exec_noop }, /* varname */
+ { exec_noop }, /* not */
+ { exec_noop }, /* plus */
+ { exec_noop }, /* and */
+ { exec_noop }, /* or */
+ { exec_noop }, /* eq */
+ { exec_noop }, /* neq */
+ { exec_noop }, /* regeq */
+ { exec_noop }, /* regneq */
+ { exec_noop }, /* buffer */
+ { exec_noop }, /* substitute */
+ { exec_noop }, /* protect */
+ { exec_noop }, /* verbatim */
+ { exec_noop }, /* getenv */
+ { exec_noop }, /* upcase */
+ { exec_noop }, /* downcase */
+ { exec_noop }, /* zvar */
+ { exec_noop }, /* get */
+ { exec_noop }, /* lany */
+ { exec_noop }, /* rany */
+ { exec_noop }, /* lbreak */
+ { exec_noop }, /* rbreak */
+ { exec_noop }, /* lspan */
+ { exec_noop }, /* rspan */
+
+ { exec_noop }, /* noop statement */
+ { exec_set },
+ { exec_fields },
+
+ { exec_print },
+ { exec_clearbuf },
+
+ { exec_appendport },
+ { exec_execport },
+ { exec_inputport },
+ { exec_outputport },
+ { exec_put },
+ { exec_closeinput },
+ { exec_closeoutput },
+ { exec_closeport },
+
+ { exec_exec },
+
+ { exec_if },
+ { exec_case },
+ { exec_while },
+ { exec_break },
+ { exec_exit },
+
+ { exec_noop }, /* if */
+ { exec_noop }, /* elseif */
+ { exec_noop }, /* else */
+ { exec_noop }, /* matchlist */
+ { exec_noop }, /* default */
+};
+
+static int exec_subtree(node)
+ Node *node;
+{
+ int retval = NOBREAK;
+
+ for (; node; node=node->next) {
+ retval = (opstuff[node->opcode].exec)(node);
+ if (retval != NOBREAK)
+ return(retval);
+ }
+
+ return(NOBREAK);
+}
+
+/***************************************************************************/
+
+static char *notice_fields;
+static notice_fields_length = 0;
+static number_of_fields = 0;
+
+static int exec_fields(node)
+ Node *node;
+{
+ for (node=node->d.nodes.first; node; node=node->next) {
+ var_set_variable_then_free_value(node->d.string_constant,
+ get_next_field(&notice_fields,
+ &notice_fields_length));
+ if (number_of_fields)
+ number_of_fields--;
+ }
+
+ var_set_variable_to_number("number_of_fields", number_of_fields);
+
+ return(NOBREAK);
+}
+
+void exec_process_packet(program, notice)
+ Node *program;
+ ZNotice_t *notice;
+{
+ notice_fields = notice->z_message;
+ notice_fields_length = notice->z_message_len;
+
+ var_set_number_variables_to_fields(notice_fields, notice_fields_length);
+
+ number_of_fields = count_nulls(notice_fields, notice_fields_length);
+ var_set_variable_to_number("number_of_fields", number_of_fields);
+
+ clear_buffer();
+ (void)exec_subtree(program);
+}