summaryrefslogtreecommitdiff
path: root/src/console.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/console.c')
-rw-r--r--src/console.c222
1 files changed, 198 insertions, 24 deletions
diff --git a/src/console.c b/src/console.c
index 13e33f7..d415500 100644
--- a/src/console.c
+++ b/src/console.c
@@ -1,14 +1,37 @@
#include "console.h"
-#include <readline/readline.h>
+#include <ctype.h>
+#include <errno.h>
-typedef struct con_var_s con_var_t;
+typedef struct con_var_s con_var;
struct con_var_s {
char *name;
char *value;
- con_var_t *next;
+ con_var *next;
};
-con_var_t *con_vars[256];
+con_var *con_vars[256];
+phy_sim *con_sim;
+
+int con_init(phy_sim *sim)
+{
+ con_var_set("test", "7");
+ con_sim = sim;
+ return 0;
+}
+
+void con_quit(void)
+{
+ size_t i;
+ con_var *var, *next;
+
+ for (i = 0; i < 256; i++)
+ for (var = con_vars[i]; var; var = next) {
+ next = var->next;
+ free(var->name);
+ free(var->value);
+ free(var);
+ }
+}
size_t con_var_hash(char *text)
{
@@ -21,10 +44,10 @@ size_t con_var_hash(char *text)
return rv & 0xFF;
}
-con_var_t *con_var_find(char *name, size_t *ret_hash)
+con_var *con_var_find(char *name, size_t *ret_hash)
{
size_t hash;
- con_var_t *var;
+ con_var *var;
hash = con_var_hash(name);
@@ -38,16 +61,16 @@ con_var_t *con_var_find(char *name, size_t *ret_hash)
return NULL;
}
-con_var_t *con_var_add(char *name)
+con_var *con_var_add(char *name)
{
- con_var_t *var;
+ con_var *var;
size_t hash;
var = con_var_find(name, &hash);
if (var)
return var;
- var = malloc(sizeof(con_var_t));
+ var = malloc(sizeof(con_var));
assert(var);
var->next = con_vars[hash];
@@ -63,7 +86,7 @@ con_var_t *con_var_add(char *name)
void con_var_set(char *name, char *value)
{
- con_var_t *var;
+ con_var *var;
var = con_var_add(name);
@@ -78,7 +101,7 @@ void con_var_set(char *name, char *value)
char *con_var_get(char *name)
{
- con_var_t *var;
+ con_var *var;
var = con_var_find(name, NULL);
if (!var)
@@ -106,32 +129,183 @@ size_t con_var_get_size(char *name)
if (!str)
return 0;
- return strtoul(name, NULL, 10);
+ return strtoul(str, NULL, 10);
}
-int con_init(void)
+typedef struct {
+ char *name;
+
+ char *(*func)(char*);
+} con_cmd;
+
+char *cmd_load(char *arg)
{
- con_var_set("kurwa", "chuj");
- return 0;
+ FILE *fp;
+ char line[1024];
+
+ fp = fopen(arg, "r");
+ if (!fp)
+ return va("%s: %s", arg, strerror(errno));
+
+ while (fgets(line, sizeof(line), fp)) {
+ con_exec(line, NULL);
+ }
+
+ fclose(fp);
+ return va("ZaƂadowano plik %s", arg);
}
+char *cmd_get(char *arg)
+{
+ if (!arg)
+ return "Brak argumentu";
-void con_quit(void)
+ return va("%s = \"%s\"", arg, con_var_get(arg));
+}
+
+char *cmd_getf(char *arg)
+{
+ if (!arg)
+ return "Brak argumentu";
+
+ return va("%s = %f", arg, con_var_get_float(arg));
+}
+
+char *cmd_getz(char *arg)
+{
+ if (!arg)
+ return "Brak argumentu";
+
+ return va("%s = %zu", arg, con_var_get_size(arg));
+}
+
+char *cmd_pause(char *arg)
{
+ itc_chan_push(&con_sim->ctl, PHY_CMD_PAUSE, NULL);
+ return "Symulacja wstrzymana";
}
+char *cmd_reset(char *arg)
+{
+ itc_chan_push(&con_sim->ctl, PHY_CMD_RESET, NULL);
+ return "Symulacja ustawiona ponownie";
+}
+char *cmd_resume(char *arg)
+{
+ itc_chan_push(&con_sim->ctl, PHY_CMD_RESUME, NULL);
+ return "Symulacja wznowiona";
+}
-int con_thread_f(phy_sim *sim)
+char *cmd_zero(char *arg)
{
- printf("%f\n", con_var_get_float("kurwa"));
+ itc_chan_push(&con_sim->ctl, PHY_CMD_ZERO, NULL);
+ return "Symulacja wyzerowana";
+}
+
+
+static const con_cmd con_cmds[] = {
+ {"get", cmd_get},
+ {"getf", cmd_getf},
+ {"getz", cmd_getz},
+ {"load", cmd_load},
+ {"pause", cmd_pause},
+ {"reset", cmd_reset},
+ {"resume", cmd_resume},
+ {"zero", cmd_zero},
+};
+
+int con_cmd_cmp(const void *a, const void *b)
+{
+ return strcmp(a, ((const con_cmd*)b)->name);
+}
+
+void con_exec(char *str, itc_chan *feedback)
+{
+ char *p, *r, *cmd_str, *arg, *response = NULL;
+ con_cmd *cmd;
+ char *(*func)(char*) = NULL;
+
+ p = str;
+ while (*p && isspace(*p))
+ p++;
+
+ if (!*p)
+ return;
- while (1) {
- char *line;
+ r = p;
- line = readline("(cem) ");
- printf("line=%s\n", line);
+ while (*p && !isspace(*p))
+ p++;
+
+ cmd_str = strndup(r, p - r);
+ assert(cmd_str);
+
+ while (*p && isspace(*p))
+ p++;
+
+ if (!*p)
+ arg = NULL;
+ else {
+ int len;
+
+ len = strlen(p);
+
+ if (p[len - 1] == '\n')
+ arg = strndup(p, len - 1);
+ else
+ arg = strndup(p, len);
+
+ assert(arg);
}
-
- return 0;
+
+ cmd = bsearch(cmd_str, con_cmds, sizeof(con_cmds) / sizeof(con_cmd),
+ sizeof(con_cmd), con_cmd_cmp);
+
+ if (!cmd) {
+ con_var *var;
+
+ var = con_var_find(cmd_str, NULL);
+ if (!var)
+ assert(asprintf(&response, "Nieznane polecenie: %s",
+ cmd_str) != -1);
+ else if (arg) {
+ con_var_set(cmd_str, arg);
+ assert(asprintf(&response, "%s <- %s", cmd_str, arg)
+ != -1);
+ }
+ else {
+ void *tmp;
+
+ func = cmd_get;
+
+ tmp = cmd_str;
+ cmd_str = arg;
+ arg = tmp;
+ }
+ } else
+ func = cmd->func;
+
+ if (func) {
+ response = func(arg);
+ if (response) {
+ response = strdup(response);
+ assert(response);
+ }
+ }
+
+ if (response) {
+ if (cmd)
+ printf("con_exec: %s: %s\n", cmd_str, response);
+ else
+ printf("con_exec: %s\n", response);
+
+ if (feedback)
+ itc_chan_push(feedback, CMD_CON_FEEDBACK, response);
+ else
+ free(response);
+ }
+
+ free(cmd_str);
+ free(arg);
}