summaryrefslogtreecommitdiff
path: root/repl.c
diff options
context:
space:
mode:
authorThomas Albers <thomas@thomaslabs.org>2023-08-06 16:04:59 +0200
committerThomas Albers <thomas@thomaslabs.org>2023-08-06 16:04:59 +0200
commit30125839213e5b81e87c4fa3d7d3f4030b3659e3 (patch)
tree183670f0617059ac7b07927adcdcc9908f4c97aa /repl.c
parentd0e2b015f25d53498da258d3ee988a101bc597fa (diff)
Merge repl.c and cmd.c commands
Diffstat (limited to 'repl.c')
-rw-r--r--repl.c356
1 files changed, 0 insertions, 356 deletions
diff --git a/repl.c b/repl.c
deleted file mode 100644
index edac70f..0000000
--- a/repl.c
+++ /dev/null
@@ -1,356 +0,0 @@
-#include <zup.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <signal.h>
-#include <errno.h>
-
-#ifdef USE_READLINE
-#include <readline/readline.h>
-#include <readline/history.h>
-#endif // USE_READLINE
-
-typedef int (*repl_command)(int, const struct param*, int, char**);
-
-static int
-repl_read(int fd, const struct param *param, int argc, char **args)
-{
- int err = 0;
- uint8_t buf[MAX_PACKET_SIZE];
-
- uint8_t bank;
- uint16_t address;
- uint16_t length;
- const char *pathname = NULL;
-
- if (argc != 3 && argc != 4)
- goto syntax_error;
-
- errno = 0;
- bank = strtoul(args[0], NULL, 16);
- err |= errno;
-
- errno = 0;
- address = strtoul(args[1], NULL, 16);
- err |= errno;
-
- errno = 0;
- length = strtoul(args[2], NULL, 16);
- err |= errno;
-
- if (argc == 4)
- pathname = args[3];
-
- if (err)
- goto syntax_error;
-
- if ((err = z_read(fd, bank, address, length, buf))) {
- print_error(err);
- return err;
- }
-
- hexdump(address, length, buf);
-
- if (pathname) {
- FILE *file;
- if (!(file = fopen(pathname, "w"))) {
- perror("File could not be opened");
- return -1;
- }
- fwrite(buf, sizeof(uint8_t), length, file);
- fclose(file);
- }
-
- return err;
-
-syntax_error:
- fputs("Usage: read <bank> <address> <length> [pathname]\n", stderr);
- return 1;
-}
-
-static int
-repl_write(int fd, const struct param *param, int argc, char **args)
-{
- int err;
- char line[512];
- uint8_t buf[MAX_PACKET_SIZE];
-
- char *p;
-
- uint8_t bank;
- uint16_t address;
- uint16_t length = 0;
-
- do {
- // TODO: Handle fgets error
- fgets(line, LEN(line), stdin);
- if (line && !strcmp("\n", line))
- break;
-
- p = strtok(line, " \n");
- while (p && length < 10) {
- errno = 0;
- buf[length++] = strtoul(p, NULL, 16);
- p = strtok(NULL, " \n");
- }
-
- if (p) {
- fputs("WRITE: Input can't be longer than 256 bytes\n", stderr);
- return -1;
- }
- } while (1);
-
- if ((err = z_write(fd, bank, address, length, buf))) {
- print_error(err);
- return err;
- }
-
- return 0;
-}
-
-static int
-repl_echo(int fd, const struct param *param, int argc, char **args)
-{
- int err;
- char line[512];
- char buf[MAX_PACKET_SIZE];
-
- memset(line, 0, sizeof(line));
- memset(buf, 0, sizeof(buf));
-
- size_t length = 0;
-
- do {
- // TODO: Handle fgets error
- fgets(line, LEN(line), stdin);
- if (line && !strcmp("\n", line))
- break;
-
- size_t len = strlen(line);
- if (line[len - 1] == '\n')
- line[--len] = '\0';
-
- if (length + len >= MAX_PACKET_SIZE) {
- fputs("ECHO: Input can't be longer than 256 bytes\n", stderr);
- return -1;
- }
-
- strcat(buf, line);
- length += len;
- } while (1);
-
- if ((err = z_echo(fd, length, (uint8_t *)buf))) {
- print_error(err);
- return err;
- }
-
- fwrite(buf, sizeof(uint8_t), length, stdout);
- putchar('\n');
- fflush(stdout);
-
- return 0;
-}
-
-static int
-repl_io_write(int fd, const struct param *param, int argc, char **args)
-{
- return 0;
-}
-
-/*
-static volatile sig_atomic_t quit = 0;
-
-void
-interrupt_handler(int signal)
-{
- puts("Bye!");
- quit = 1;
- // fclose(stdin);
-}
-*/
-
-enum args_type {
- A_END,
- A_BYTE,
- A_DBYTE,
- A_QBYTE,
- A_OBYTE,
- A_STRING,
- A_OPTIONAL = 16
-};
-
-struct command;
-
-typedef int (*fptr)(int, const struct command *, struct param *, int, char **);
-
-struct command {
- char alias;
- const char *name;
- int *args_spec;
- const char *usage;
- fptr fptr;
- int quit;
-};
-
-static int
-parse_args(const struct command *cmd, int argc, char **args, ...)
-{
- int i = 0;
- int opt = 0;
- int err = 0;
- va_list ap;
- va_start(ap, args);
-
- void *ptr = NULL;
- int *p = cmd->args_spec;
-
- for ( ; *p != A_END; ++p) {
- // Avoid runaway p
- assert(i < MAX_ARGS);
-
- if (*p == A_OPTIONAL) {
- opt = 1;
- continue;
- }
-
- if (i == argc && !opt)
- goto syntax_error;
-
- ptr = va_arg(ap, void *);
- errno = 0;
- char *end = NULL;
-
- switch (*p) {
- case A_BYTE:
- *((uint8_t *)ptr) = strtoul(args[i], &end, 16);
- break;
-
- case A_DBYTE:
- *((uint16_t *)ptr) = strtoul(args[i], &end, 16);
- break;
-
- case A_STRING:
- *((const char **)ptr) = args[i];
- break;
- }
-
- if (errno || args[i] == end) {
- fprintf(stderr, "Invalid argument: %s\n", args[i]);
- goto syntax_error;
- }
-
- ++i;
- }
-
- va_end(ap);
- return i;
-
-syntax_error:
- va_end(ap);
- fputs(cmd->usage, stderr);
- return -1;
-}
-
-#define ARGS(...) (int []){__VA_ARGS__}
-
-static int
-repl_io_read(int fd, const struct param *param, int argc, char **args)
-{
- uint8_t bank;
- uint16_t address;
- const char *filename = NULL;
-
- struct command cmd = {
- .alias = 'i',
- .name = "io_read",
- .usage = "",
- .fptr = NULL,
- .quit = 0,
- .args_spec = ARGS(A_BYTE, A_DBYTE, A_OPTIONAL, A_STRING, A_END),
- .usage = "Usage: read <bank> <address> <length> [pathname]\n"
- };
-
- parse_args(&cmd, argc, args, &bank, &address, &filename);
- printf("result: %hhx %hx %s\n", bank, address, filename);
- return 0;
-}
-
-// TODO: Handle signals (CTRL-C)
-// TODO: Print errors when in repl and crash if from terminal
-void
-repl(int fd, struct param *param)
-{
- struct command {
- const char *name;
- repl_command fptr;
- int quit;
- };
-
- const struct command cmd_table[] = {
- {"read", repl_read, 0},
- {"write", repl_write, 0},
- {"echo", repl_echo, 0},
- {"io_read", repl_io_read, 0},
- {"io_write", repl_io_write, 0},
- {"quit", NULL, 1}
- };
-
- int quit = 0;
-
-#ifdef USE_READLINE
- using_history();
-#endif
-
- while (!quit) {
-#ifdef USE_READLINE
- char *line = readline("* ");
-
- if (!line)
- break;
-
- add_history(line);
-#else
- size_t len = 0;
- char line[512];
- fputs("* ", stdout);
-
- if (!fgets(line, sizeof(line), stdin))
- break;
-
- len = strlen(line);
- if (line[len - 1] == '\n')
- line[len - 1] = '\0';
-#endif
- int argc = 1;
- char *args[MAX_ARGS] = { NULL };
-
- // Parse command
- args[0] = strtok(line, " ");
- if (!args[0])
- goto skip;
- while(argc < MAX_ARGS && (args[argc] = strtok(NULL, " ")))
- ++argc;
-
- // Match action
- int cmdi;
- for (cmdi = 0; cmdi < LEN(cmd_table); ++cmdi) {
- if (!strcmp(args[0], cmd_table[cmdi].name))
- break;
- }
-
- // Call action
- if (cmdi == LEN(cmd_table)) {
- fprintf(stdout, "Unknown command %s\n", args[0]);
- } else {
- repl_command fptr = cmd_table[cmdi].fptr;
- if (fptr)
- fptr(fd, param, argc - 1, &args[1]);
- quit = cmd_table[cmdi].quit;
- }
- skip:
-#ifdef USE_READLINE
- free(line);
-#endif
- }
-}