diff --git a/ui/main.c b/ui/main.c index 7950dd9..640b9be 100644 --- a/ui/main.c +++ b/ui/main.c @@ -53,9 +53,12 @@ #include "goodfet.h" #include "input.h" +#define OPT_NO_RC 0x01 +#define OPT_EMBEDDED 0x02 + struct cmdline_args { const char *driver_name; - int no_rc; + int flags; struct device_args devarg; }; @@ -120,6 +123,8 @@ static void usage(const char *progname) " on the driver.\n" " --version\n" " Show copyright and version information.\n" +" --embedded\n" +" Run in embedded mode.\n" "\n" "Most drivers connect by default via USB, unless told otherwise via the\n" "-d option. By default, the first USB device found is opened.\n" @@ -207,6 +212,7 @@ static int parse_cmdline_args(int argc, char **argv, {"force-reset", 0, 0, 'R'}, {"allow-fw-update", 0, 0, 'A'}, {"require-fw-update", 1, 0, 'M'}, + {"embedded", 0, 0, 'E'}, {NULL, 0, 0, 0} }; int want_usb = 0; @@ -224,6 +230,10 @@ static int parse_cmdline_args(int argc, char **argv, } break; + case 'E': + args->flags |= OPT_EMBEDDED; + break; + case 'A': args->devarg.flags |= DEVICE_FLAG_DO_FWUPDATE; break; @@ -277,7 +287,7 @@ static int parse_cmdline_args(int argc, char **argv, break; case 'n': - args->no_rc = 1; + args->flags |= OPT_NO_RC; break; case 'P': @@ -378,6 +388,8 @@ int main(int argc, char **argv) if (input_module->init() < 0) return -1; + output_set_embedded(args.flags & OPT_EMBEDDED); + if (sockets_init() < 0) return -1; @@ -392,7 +404,7 @@ int main(int argc, char **argv) simio_init(); - if (!args.no_rc) + if (!(args.flags & OPT_NO_RC)) process_rc_file(); /* Process commands */ diff --git a/ui/reader.c b/ui/reader.c index 43dfae4..937866e 100644 --- a/ui/reader.c +++ b/ui/reader.c @@ -137,6 +137,7 @@ void reader_loop(void) char tmpbuf[MAX_READER_LINE]; char *buf = tmpbuf; + printc_shell("ready\n"); if (input_module->read_command(tmpbuf, sizeof(tmpbuf))) break; @@ -146,6 +147,8 @@ void reader_loop(void) memcpy(tmpbuf, repeat_buf, sizeof(tmpbuf)); ctrlc_clear(); + + printc_shell("busy\n"); do_command(buf, 1); if (want_exit) diff --git a/util/output.c b/util/output.c index e5b901a..5dade7d 100644 --- a/util/output.c +++ b/util/output.c @@ -31,6 +31,7 @@ static capture_func_t capture_func; static void *capture_data; +static int is_embedded_mode; #define LINEBUF_SIZE 4096 @@ -133,13 +134,18 @@ static void emit_ansi(const char *code, int len, int ansi_state, FILE *out) * be nul-terminated with no line-ending characters. Embedded ANSI * sequences are handled appropriately. */ -static void handle_line(const char *text, FILE *out) +static void handle_line(const char *text, FILE *out, char sigil) { const int want_color = opdb_get_boolean("color"); char cap_buf[LINEBUF_SIZE]; int cap_len = 0; int ansi_state = 7; + if (is_embedded_mode) { + out = stdout; + fputc(sigil, out); + } + while (*text) { int r; @@ -180,7 +186,8 @@ static void handle_line(const char *text, FILE *out) * we're currently within an ANSI code, so pushing code fragments works * correctly. */ -static int write_text(struct linebuf *ob, const char *text, FILE *out) +static int write_text(struct linebuf *ob, const char *text, + FILE *out, char sigil) { int count = 0; @@ -192,7 +199,7 @@ static int write_text(struct linebuf *ob, const char *text, FILE *out) ob->buf[ob->len] = 0; ob->len = 0; ob->ansi_mode = 0; - handle_line(ob->buf, out); + handle_line(ob->buf, out, sigil); } else { if (*text == 0x1b) ob->ansi_mode = 1; @@ -215,6 +222,7 @@ static int write_text(struct linebuf *ob, const char *text, FILE *out) static struct linebuf lb_normal; static struct linebuf lb_debug; static struct linebuf lb_error; +static struct linebuf lb_shell; int printc(const char *fmt, ...) { @@ -225,7 +233,7 @@ int printc(const char *fmt, ...) vsnprintf(buf, sizeof(buf), fmt, ap); va_end(ap); - return write_text(&lb_normal, buf, stdout); + return write_text(&lb_normal, buf, stdout, ':'); } int printc_dbg(const char *fmt, ...) @@ -240,7 +248,7 @@ int printc_dbg(const char *fmt, ...) vsnprintf(buf, sizeof(buf), fmt, ap); va_end(ap); - return write_text(&lb_debug, buf, stdout); + return write_text(&lb_debug, buf, stdout, '-'); } int printc_err(const char *fmt, ...) @@ -252,7 +260,27 @@ int printc_err(const char *fmt, ...) vsnprintf(buf, sizeof(buf), fmt, ap); va_end(ap); - return write_text(&lb_error, buf, stderr); + return write_text(&lb_error, buf, stderr, '!'); +} + +int printc_shell(const char *fmt, ...) +{ + char buf[4096]; + va_list ap; + + if (!is_embedded_mode) + return 0; + + va_start(ap, fmt); + vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + + return write_text(&lb_shell, buf, stdout, '\\'); +} + +void output_set_embedded(int enable) +{ + is_embedded_mode = enable; } void pr_error(const char *prefix) diff --git a/util/output.h b/util/output.h index 7d1c7b9..b82fe67 100644 --- a/util/output.h +++ b/util/output.h @@ -33,9 +33,25 @@ int printc_dbg(const char *fmt, ...) __attribute__((format (printf, 1, 2))); int printc_err(const char *fmt, ...) __attribute__((format (printf, 1, 2))); +int printc_shell(const char *fmt, ...) + __attribute__((format (printf, 1, 2))); void pr_error(const char *prefix); +/* Enable embedded output mode. When enabled, all logical streams + * are sent to stdout (not stderr), and prefixed with the following + * sigils: + * + * : normal + * ! error + * - debug + * \ shell + * + * Additionally, ANSI codes are used for colourized output on Windows + * instead of changing the console text attributes. + */ +void output_set_embedded(int enable); + /* Capture output. Capturing is started by calling capture_begin() with * a callback function. The callback is invoked for each line of output * printed to either stdout or stderr (output still goes to