From f0b4716cdc3763e5adfaf6ba16bb8261007c8e02 Mon Sep 17 00:00:00 2001 From: jp7g21 <jp7g21@soton.ac.uk> Date: Sun, 14 Nov 2021 11:58:38 +0000 Subject: [PATCH] Final tweaks --- drake/test1/main | Bin 0 -> 24408 bytes drake/test2/Makefile | 3 + duck/duck.c | 9 +- gduckb/Makefile | 2 + gduckb/gdbinit | 2 + gduckb/gduckb.c | 231 +++++++++++++++++++++++++++++++++++++++++++ libduck/libduck.c | 17 +++- libduck/libduck.h | 2 + 8 files changed, 255 insertions(+), 11 deletions(-) create mode 100755 drake/test1/main create mode 100644 drake/test2/Makefile create mode 100644 gduckb/Makefile create mode 100644 gduckb/gdbinit create mode 100644 gduckb/gduckb.c diff --git a/drake/test1/main b/drake/test1/main new file mode 100755 index 0000000000000000000000000000000000000000..f184c09488f33bb06aa276cba7bcc7e9ca63bc0a GIT binary patch literal 24408 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 literal 0 HcmV?d00001 diff --git a/drake/test2/Makefile b/drake/test2/Makefile new file mode 100644 index 0000000..9152907 --- /dev/null +++ b/drake/test2/Makefile @@ -0,0 +1,3 @@ + +all: + ls /doesntexist diff --git a/duck/duck.c b/duck/duck.c index 280eb9e..3f52e8f 100644 --- a/duck/duck.c +++ b/duck/duck.c @@ -82,15 +82,12 @@ int main(int argc, char **argv) } else if (strcmp(argv[i], "nod") == 0) { if (argv[i+1]) { int numnods = atoi(argv[i+1]); - shake(MOTOR_2, numnods, -90, 0, 250); + shake(MOTOR_2, numnods, 0, 90, 250); i++; } } else if (strcmp(argv[i], "facepalm") == 0) { - if (argv[i+1]) { - int numnods = atoi(argv[i+1]); - shake(MOTOR_2, numnods, -90, 0, 250); - i++; - } + duck_set_velocity(2, 30, 3000); + duck_delay(3000); } else if (strcmp(argv[i], "print") == 0) { if (argv[i+1]) { duck_write_text(argv[i+1]); diff --git a/gduckb/Makefile b/gduckb/Makefile new file mode 100644 index 0000000..7862772 --- /dev/null +++ b/gduckb/Makefile @@ -0,0 +1,2 @@ +gduckb: gduckb.c ../libduck/libduck.so + cc gduckb.c -o gduckb -L ../libduck -l duck -g diff --git a/gduckb/gdbinit b/gduckb/gdbinit new file mode 100644 index 0000000..1ca4a9c --- /dev/null +++ b/gduckb/gdbinit @@ -0,0 +1,2 @@ +b main +r a.out diff --git a/gduckb/gduckb.c b/gduckb/gduckb.c new file mode 100644 index 0000000..8efabd4 --- /dev/null +++ b/gduckb/gduckb.c @@ -0,0 +1,231 @@ +#include <stdio.h> +#include <ctype.h> +#include <string.h> +#include <time.h> +#include <err.h> +#include <stdlib.h> +#include <poll.h> +#include <unistd.h> +#include <fcntl.h> +#include "../libduck/libduck.h" + +int this_in_gdb_out[2]; +int gdb_in_this_out[2]; + +void setup_pipes(void) +{ + if (pipe(gdb_in_this_out) || + pipe(this_in_gdb_out)) err(EXIT_FAILURE, "Pipe failed"); + /*this_in_gdb_out[0] = STDIN_FILENO; + gdb_in_this_out[1] = STDOUT_FILENO;*/ +} + +void launch_gdb(const char *prog) +{ + int res = fork(); + if (res < 0) { + err(EXIT_FAILURE, "fork failed"); + } else if (res == 0) { /* Child */ + dup2(gdb_in_this_out[0], STDIN_FILENO); + dup2(this_in_gdb_out[1], STDOUT_FILENO); + + if (execl("/bin/gdb", "/bin/gdb", "--interpreter=mi3", "-x", "gdbinit", prog, (char *)NULL)) { + err(EXIT_FAILURE, "Failed to launch gdb"); + } + } else { /* Parent */ + return; + } +} + +enum { + STATE_LINENO, STATE_WHITESPACE, STATE_CODE, STATE_NL +}; + +void process_code_line(const char *str) +{ + if (str[0] != '~' || str[1] != '"') return; + + int state = STATE_LINENO; + static char lineno_buf[20]; + int lb_ind = 0; + int lineno; + static char code_buf[200]; + int code_ind = 0; + int esc = 0; + + for (const char *c=str+2; *c; c++) { + switch (state) { + case STATE_LINENO: + if (isdigit(*c)) { + lineno_buf[lb_ind++] = *c; + } else if (c[0] == '\\' && c[1] == 't') { + lineno_buf[lb_ind] = 0; + lineno = atoi(lineno_buf); + if (lineno <= 0) return; + state = STATE_WHITESPACE; + c += 2; + } + break; + case STATE_WHITESPACE: + if (!isspace(*c)) { + state = STATE_CODE; + code_buf[code_ind++] = *c; + } + break; + case STATE_CODE: + if (esc) { + if (*c == 't') code_buf[code_ind++] = '\t'; + if (*c == '\\') code_buf[code_ind++] = '\\'; + if (*c == '"') code_buf[code_ind++] = '"'; + if (*c == '\'') code_buf[code_ind++] = '\''; + if (*c == 'n') state = STATE_NL; + esc = 0; + } else if (*c == '\\') { + esc = 1; + } else { + code_buf[code_ind++] = *c; + } + break; + case STATE_NL: + code_buf[code_ind] = 0; + duck_write_text(code_buf); + break; + } + } +} + +/* Line of code is last ~ line before prompt, matching line pattern */ + +enum { STATE_PROMPT, STATE_TILDE_LINE, STATE_OTHER_LINE }; + +void parse_line(const char *line) +{ + static int state = STATE_OTHER_LINE; + static char codelinebuf[200]; + + switch (state) { + case STATE_PROMPT: + if (line[0] == '~') { + state = STATE_TILDE_LINE; + strncpy(codelinebuf, line, 199); + } + break; + case STATE_TILDE_LINE: + if (line[0] != '~') { + state = STATE_OTHER_LINE; + process_code_line(codelinebuf); + } + break; + case STATE_OTHER_LINE: + if (strcmp(line, "(gdb)") == 0) { + state = STATE_PROMPT; + } + if (line[0] == '~') process_code_line(line); + break; + } +} + + +char buf[4096]; +int buf_ind = 0; + +char linebuf[200]; +int linebuf_ind = 0; + +void read_data(void) +{ + int n; + + if ((n=read(this_in_gdb_out[0], buf, 4065)) <= 0) { + return; + } else { + for (int i=0; i < n; i++) { + if (buf[i] == '\n') { + linebuf[linebuf_ind] = '\0'; + parse_line(linebuf); + linebuf_ind = 0; + } else { + linebuf[linebuf_ind++] = buf[i]; + } + } + } +} + +void sleep_ms(int ms) +{ + struct timespec ts = { + .tv_sec=ms/1000, .tv_nsec=(ms % 1000) * 1000000 + }; + nanosleep(&ts, NULL); +} + +void shake(int motor, int number, int min, int max, int delay) +{ + int delay1 = (delay * (-min)) / (max - min); + int delay2 = delay - delay1; + + duck_set_velocity(motor, 100, 100); + duck_delay(100); + duck_set_velocity(motor, -100, 200); + duck_delay(200); + duck_set_velocity(motor, 100, 100); + duck_delay(100); +} +int interact_gdb(void) +{ + FILE *to_gdb = fdopen(gdb_in_this_out[1], "w"); + if (!to_gdb) err(EXIT_FAILURE, "fdopen failed"); + setbuf(to_gdb, NULL); + + struct pollfd fds[] = { + { .fd = this_in_gdb_out[0], POLLIN, 0 }, + { .fd = duckfd, POLLIN, 0 }, + }; + + static char tmp[4096]; + + /*read(this_in_gdb_out[0], tmp, 4096); + fprintf(to_gdb, "b main\n"); + sleep_ms(300); + read(this_in_gdb_out[0], tmp, 4096); + fprintf(to_gdb, "r\n");*/ + sleep_ms(300); + + while (1) { + if (poll(fds, 2, -1)) { + if (fds[0].revents) { + read_data(); + fds[0].revents = 0; + } + if (fds[1].revents) { + int c = duck_getc(); + fprintf(to_gdb, c == 'a' ? "s\n" : "n\n"); + shake(MOTOR_1, 2, -20, 20, 200); + fds[1].revents = 0; + } + } + } +} + + + +int main(int argc, char **argv) +{ + duck_debug_mode = 0; + if (argc < 2) { + printf("Usage: gduckb program-name\n"); + return -1; + } + + setup_pipes(); + launch_gdb("a.out"); + open_duck(DEFAULT_DUCK_FNAME); + configure_duck(); + + if (interact_gdb()) { + err(EXIT_FAILURE, "gdb interaction failed"); + } + close_duck(); + return 0; + +} diff --git a/libduck/libduck.c b/libduck/libduck.c index d0e210f..f967f3f 100644 --- a/libduck/libduck.c +++ b/libduck/libduck.c @@ -11,14 +11,14 @@ # define DUCK_BAUD B115200 #endif /* DUCK_BAUD */ -static int duckfd = 0; +int duckfd = 0; int duck_debug_mode = 0; void open_duck(const char *fname) { if (duck_debug_mode) { - printf("Opening duck\n"); + fprintf(stderr, "Opening duck\n"); } else { duckfd = open(fname, O_NOCTTY | O_RDWR); @@ -31,7 +31,7 @@ void open_duck(const char *fname) void configure_duck(void) { if (duck_debug_mode) { - printf("Configuring duck\n"); + fprintf(stderr, "Configuring duck\n"); } else { struct termios tio; if (tcgetattr(duckfd, &tio)) { @@ -51,7 +51,7 @@ static int duck_printf(const char *fmt, ...) va_list ap; va_start(ap, fmt); if (duck_debug_mode) { - return vprintf(fmt, ap); + return vfprintf(stderr, fmt, ap); } else { return vdprintf(duckfd, fmt, ap) < 0; } @@ -103,10 +103,17 @@ void read_duck_to_stdout(void) } } +int duck_getc(void) +{ + char c; + if (read(duckfd, &c, 1)) return c; + else return EOF; +} + void close_duck(void) { if (duck_debug_mode) { - printf("Closing duck\n"); + fprintf(stderr, "Closing duck\n"); } else { close(duckfd); } diff --git a/libduck/libduck.h b/libduck/libduck.h index 9ce0166..524c3de 100644 --- a/libduck/libduck.h +++ b/libduck/libduck.h @@ -10,6 +10,7 @@ #endif /* DEFAULT_DUCK_FNAME */ extern int duck_debug_mode; +extern int duckfd; void open_duck(const char *fname); void configure_duck(void); @@ -18,6 +19,7 @@ int duck_delay(int ms); int duck_set_velocity(int motor, int deg_per_sec, int ms); int duck_write_text(const char *str); void read_duck_to_stdout(void); +int duck_getc(void); void close_duck(void); #endif /* _LIBDUCK_H */ -- GitLab