Commit f0b4716c authored by jp7g21's avatar jp7g21
Browse files

Final tweaks

parent a0e84966
all:
ls /doesntexist
......@@ -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]);
......
gduckb: gduckb.c ../libduck/libduck.so
cc gduckb.c -o gduckb -L ../libduck -l duck -g
b main
r a.out
#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;
}
......@@ -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);
}
......
......@@ -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 */
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment