#include "console.h" #include #include typedef struct con_var_s con_var; struct con_var_s { char *name; char *value; con_var *next; }; 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) { char *p; size_t rv; for (rv = 0, p = text; *p; p++) rv += 119 * ((*p) + 83); return rv & 0xFF; } con_var *con_var_find(char *name, size_t *ret_hash) { size_t hash; con_var *var; hash = con_var_hash(name); if (ret_hash) *ret_hash = hash; for (var = con_vars[hash]; var; var = var->next) if (!strcmp(var->name, name)) return var; return NULL; } con_var *con_var_add(char *name) { con_var *var; size_t hash; var = con_var_find(name, &hash); if (var) return var; var = malloc(sizeof(con_var)); assert(var); var->next = con_vars[hash]; con_vars[hash] = var; var->name = strdup(name); assert(var->name); var->value = NULL; return var; } void con_var_set(char *name, char *value) { con_var *var; var = con_var_add(name); free(var->value); if (value) { var->value = strdup(value); assert(var->value); } else var->value = NULL; } char *con_var_get(char *name) { con_var *var; var = con_var_find(name, NULL); if (!var) return NULL; return var->value; } float con_var_get_float(char *name) { char *str; str = con_var_get(name); if (!str) return 0.0f; return atof(str); } size_t con_var_get_size(char *name) { char *str; str = con_var_get(name); if (!str) return 0; return strtoul(str, NULL, 10); } typedef struct { char *name; char *(*func)(char*); } con_cmd; char *cmd_load(char *arg) { 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_csg_clear(char *arg) { itc_chan_push(&con_sim->ctl, PHY_CMD_CSG_CLEAR, NULL); return "Wyzerowano przenikalność elektryczną"; } char *cmd_csg_push(char *arg) { itc_chan_push(&con_sim->ctl, PHY_CMD_CSG_PUSH, NULL); return "Wykonano operację na przenikalności elektrycznej"; } char *cmd_get(char *arg) { if (!arg) return "Brak argumentu"; 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"; } char *cmd_zero(char *arg) { itc_chan_push(&con_sim->ctl, PHY_CMD_ZERO, NULL); return "Symulacja wyzerowana"; } static const con_cmd con_cmds[] = { {"csg-clear", cmd_csg_clear}, {"csg-push", cmd_csg_push}, {"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; r = p; 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); } 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); }