Skip to content
Snippets Groups Projects
Commit f0b4716c authored by jp7g21's avatar jp7g21
Browse files

Final tweaks

parent a0e84966
No related branches found
No related tags found
No related merge requests found
File added
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 */
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment